2011-04-28 48 views
4

我的理解是,除了别的以外,还可以使用指针来允许您在需要时动态分配内存(并知道需要多少内存),而不是预先静态分配数组。何时通过指针使用数组,或反之亦然

我很难确定何时它更好地节省动态分配的计算时间,并选择较大的内存占用量与较大的内存占用量并使用一些计算时间来分配我只需要的内存。

有人可以在这个问题上谈一点点?有任何一般规则可能有帮助吗?

回答

1

你应该使用动态分配内存时:

  • 你不知道你会多少内存需要在编译时
  • 的内存量运行时变化
  • 需要大量内存

你应该使用静态分配内存时:

  • 你在编译时间
  • 所需的内存量知道的大小是低

使用动态分配的内存需要系统的使用呼叫,这是当你编程问什么操作系统。你有速度惩罚,因为这个过程可能会失去给另一个过程的“处理时间”。操作系统需要做很多事情来完成呼叫。做一个询问内存的系统调用是一个比写入存储在进程栈中的数组更重的过程。

+0

有没有一种很好的方法来定义“所需内存量低”中的“低”。我对这个门槛在哪里没有很好的理解。 – Mark 2011-04-28 03:32:54

+0

这真的是我想问的问题的核心(但可能做得不好)。不过,我仍然对你可能考虑的低内存阈值感兴趣。 – Mark 2011-04-28 03:42:19

+0

@Mark:如果你可以“存储”你需要的所有内存,那么堆栈有一个限制,可能是“低”。但请注意,所有函数都使用堆栈,因此如果许多函数使用内存,则可以在堆栈溢出中运行。有时使用动态内存更安全。这完全取决于程序需要多少内存以及哪个操作系统正在工作。没有一个规则是大的或低的,它的正义经验。 – anizzomc 2011-04-28 05:38:07

0

当您的数据是动态的时候使用动态容器,或者您需要从程序的不同区域传递数据。

1 - 动态数据 假设你有你的邻居列表。他们在你的街道上建一座新房子,你必须增加一个人到名单上,但你只给15个邻居分配了足够的空间。这个动态内存将允许您增加该容器的大小。这不是真的如何运作。实际上,它会找到所需大小的一块新内存,然后将旧容器复制过来。

或者另一个例子。假设你正在编写一个跟踪地址簿的程序。你的一个用户有10个联系人。另一个用户是一家公司,有5万名员工需要存储在这个地址簿中。您不想为拥有十个联系人的用户分配50000个空间,因此您可以精确分配您需要的数量。

2 - 传递数据 当您分配静态数据时,它将被放置在堆栈上,然后超出范围后将无法访问。所以如果你调用一些生成你的数组的函数,然后把数组的内存地址传回给调用者,你会得到一个运行时错误。这是因为在该函数退出后,该数组超出了范围,因此它弹出堆栈。

但是,如果您动态分配它,它就会在堆上,直到您释放它或直到程序退出时才会释放。所以你可以只保留一个指向数组开头的指针,并在整个程序中使用它,而不用担心它会超出范围,直到你想要。

+0

谢谢阿拉斯穆森,我很欣赏这种见解。我的兴趣真的在你的第二个地址簿中。从数组切换到指针的阈值在哪里?如果员工的最大数量是100,而不是50000,该怎么办?这只是一个判断呼叫还是有规定? – Mark 2011-04-28 03:26:40

+0

我会一直这样动态地做。对硬编码的某些价值没有意义,因为那样你就限制了你的程序,而你正在使用的内存不需要使用。那时,内存中唯一的限制是他们的硬件/设置,而不是你的程序。此外,我唯一一次使用静态值的时候,数组始终是完全相同的大小。所以如果你存储三维坐标的位置,总是有三个坐标,所以你可以使用一个有三个值的数组。没有意义,使这种动态。 – 2011-04-28 03:28:11

0

数组只是连续的内存块。当声明的阵列,则指针

int foo[5]; 

foo(没有索引)是一个指针,指向数组中的第一个元素。

foo[0] = 1; 
*foo = 1; 

那些做同样的事情,因为这样做:

foo[1] = 2; 
*(foo + 1) = 2; 

当您使用您所创建的堆栈上int foo[5];阵列。这对当前函数是本地的,一旦从函数返回,它就不再有效。如果您malloc()内存,您要创建堆上的阵列(并有指向它的指针)

int *foo = malloc(sizeof(int) * 5); 
foo[0] = 1; 
*foo = 1; 

你必须自己管理这个内存,free()它,当你用它做:

free(foo); 
1

通常,当您知道要处理的数据的总大小或至少是最大数据大小时,您想使用数组。如果你真的不希望有巨大的变化 - 如果(例如)变量是10到20个项目,那么最简单的方法就是分配20个,不管这个变量是多少,并且用它来完成(除非每个项目都是真的是大)。

如果您提前了解数据的大小,或者(和重要的可能性)可能很容易处理太多计划放入堆栈,动态分配变得更有用。动态分配的主要弱点是,如果你需要知道大小,你需要自己跟踪它,这取决于你在完成任务时是否释放内存。 C中的许多问题(特别是困难,烦人的问题)可以归结为在释放内存后使用内存,或者在完成后忘记释放内存。

0

虽然这个问题有一个公认的答案。让我谈谈一个稍微不同的事情。在C中,有时你可以使用一个大小在运行时确定的数组。例如:

void foo (int a[], int n) { 
    int buf[n]; 
    /* do something with buf[] */ 
} 

这种类型的数组在堆栈中分配并且大小可变。与做malloc的区别在于你不需要free()的内存;当函数调用存在时,这被照顾。当然这也意味着你可能不能返回数组的地址。

相关问题