为什么在编译时声明数组大小有限?

时间:2011-06-29 03:03:10

标签: c arrays memory-management local-variables

例如我可以做

int *arr;
arr = (int *)malloc(sizeof(int) * 1048575);

但如果没有程序崩溃,我就无法做到这一点:

int arr[1048575];

为什么会这样?

3 个答案:

答案 0 :(得分:11)

假设arr是一个局部变量,将它声明为一个数组使用来自(相对有限的)堆栈的内存,而malloc()使用来自(相对无限的)堆的内存。

答案 1 :(得分:2)

如果你在函数中将这些作为局部变量分配(这是唯一可以让指针声明紧跟malloc调用的地方),那么区别在于malloc将分配来自堆的一大块内存并给你它的地址,而直接执行int arr[1048575];将尝试在堆栈上分配内存。堆栈的可用空间要小得多。

由于我所知道的两个主要原因,堆栈的大小有限:

  1. 传统的命令式编程很少使用递归,因此深度递归(以及繁重的堆栈增长)“可能”是无限递归的标志,因此会破坏该过程的错误。因此,最好是在之前捕获进程消耗了数十亿字节的虚拟内存(在32位架构上),这将导致进程耗尽其地址空间(此时机器可能正在使用远处)虚拟内存比实际拥有的内存更多,因此运行速度非常慢。)
  2. 多线程程序需要多个堆栈。因此,运行时系统需要知道堆栈永远不会超出某个边界,因此如果创建了新的线程,它可以在该绑定之后放置另一个堆栈。

答案 2 :(得分:1)

声明数组时,将它放在堆栈上。

当你调用malloc()时,内存将从堆中获取。

与堆相比,堆栈通常更有限,并且通常是瞬态的(但这取决于您进入和退出声明此数组的函数的频率。

对于如此大的(可能不是今天的标准?)内存,最好使用malloc它,假设您希望数组能够持续一段时间。