堆栈内存是否有限制?

我正在经历其中一个主题。 一个程序崩溃了,因为它在函数内部声明了一个10 ^ 6的数组。

给出的原因是堆栈上的内存分配失败导致崩溃。

当全局声明相同的数组时,它运行良好。(堆上的内存保存了它)。

现在,让我们假设,堆栈向下增长并向上堆积。

我们有:

– -堆 – –

——————-

– -堆 – –

现在,我相信如果堆栈上的分配失败,它也必须在堆上失败。

所以我的问题是:堆栈大小有限制吗? (超过限制导致程序崩溃)。 或者我错过了什么?

这完全取决于您使用的语言和编译器。 但是使用例如C或C ++编译的程序在程序启动时分配固定大小的堆栈。 堆栈的大小通常可以在编译时指定(在我的特定编译器上它默认为1 MB)。

是的,堆栈总是有限的。 在多种语言/编译器中,您可以设置所需的大小。

通常默认值(如果没有手动设置) 对于当前语言大约是1MB ,这是足够的,除非你做一些通常不推荐的事情(比如你在堆栈上分配大数组)

与目前为止的所有答案相反,在使用GCC的Linux上(我想对于所有现代POSIX操作系统都是如此),最大堆栈大小是操作系统强制执行的安全限制,可以轻松解除。

我精心设计了一个小程序,它递归调用一个函数,直到在堆栈上分配至少10 GB,等待终端上的输入,然后安全地从所有递归调用返回到main

 #include  #include  #include  #include  void grow(unsigned cur_size) { if(cur_size * sizeof(int) < 10ul*1024ul*1024ul*1024ul) { unsigned v[1000]; v[0] = cur_size; for(unsigned i = 1; i < 1000; ++i) { v[i] = v[i-1] + 1; } grow(cur_size + 1000); for(unsigned i = 0; i < 1000; ++i) { if(v[i] != cur_size + i) puts("Error!"); } } else { putchar('#'); getchar(); } } int main() { struct rlimit l; l.rlim_max = RLIM_INFINITY; l.rlim_cur = RLIM_INFINITY; setrlimit(RLIMIT_STACK, &l); grow(0); putchar('#'); getchar(); } 

你没有提到哪种编程语言,但在Delphi中,编译选项包括最大和最小堆栈大小,我相信所有编译语言都会存在类似的参数。

我当然不得不偶尔增加自己的最大值。

是的,大多数语言的堆栈大小都有限制。 例如,在C / C ++中,如果你有一个不正确编写的递归函数(例如不正确的基本情况),你将溢出堆栈。 这是因为,忽略尾递归 ,每次调用函数都会创建一个占用堆栈空间的新堆栈帧 。 这样就够了,你的空间就会用完。

在Windows上运行此C程序(VS2008)…

 void main() { main(); } 

…导致堆栈溢出:

Unhandled exception at 0x004113a9 in Stack.exe: 0xC00000FD: Stack overflow.

也许不是一个非常好的答案,但是让你更深入地了解Windows如何管理内存: 推动Windows的极限