8

例如我可以做

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

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

int arr[1048575];

为什么会这样?

4

3 回答 3

11

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

于 2011-06-29T03:05:40.710 回答
2

如果您将这些分配为函数中的局部变量(这是唯一可以在malloc调用后立即声明指针的地方),那么不同之处在于malloc将从堆中分配一块内存并为您提供它的地址,而直接做int arr[1048575];将尝试在堆栈上分配内存。堆栈的可用空间要少得多。

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

  1. 传统的命令式编程很少使用递归,因此深度递归(和大量堆栈增长)“可能”是无限递归的标志,因此是一个会杀死进程的错误。因此,最好在进程消耗千兆字节的虚拟内存(在 32 位架构上)之前捕获它,这将导致进程耗尽其地址空间(此时机器使用的虚拟内存可能比它实际拥有的多得多) RAM,因此运行速度非常慢)。
  2. 多线程程序需要多个堆栈。因此,运行时系统需要知道堆栈永远不会超过某个界限,因此如果创建新线程,它可以在该界限之后放置另一个堆栈。
于 2011-06-29T03:08:09.977 回答
1

当你声明一个数组时,你就是把它放在堆栈上。

当你调用 malloc() 时,内存是从堆中取出的。

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

对于这么大的内存(也许不是今天的标准?),最好是 malloc 内存,假设您希望数组持续一段时间。

于 2011-06-29T03:10:42.587 回答