2009-11-22 62 views
1

在C++中,堆栈段在编译器放弃之前可以增长多少,并且说它不能为堆栈分配更多的内存。Linux 32位机器上程序的堆栈分配限制

在linux(fedora)32位机器上使用gcc。

+4

您是否正在讨论堆栈在* runtime *时可以增长多少,或者编译时编译器为一个*单个帧分配了多少空间?在运行时,编译器不会成为放弃的部分。 – 2009-11-22 18:43:35

+0

是的,在运行时可以为程序堆栈增长多少,是否有限制 – kal 2009-11-22 18:45:40

回答

10

在UNIX环境下,如果你正在运行bash运行

$ ulimit -a 

它会列出各种限制,包括堆栈大小。我的是8192kb。您可以使用ulimit来更改限制。

此外,您可以使用ulimit()函数在程序中设置各种限制。

$ man 3 ulimit 

在Windows看到StackReserveSizeStackCommitSize

在实践堆栈地址在高地址(32位的平台上,靠近3GB极限)和减小开始而存储器分配开始于低地址。这允许堆栈和内存增长,直到整个内存耗尽。

2

在我的32位linux上,它的8192K字节。所以它应该在你的机器上是相同的。

$ uname -a 
Linux TomsterInc 2.6.28-14-generiC#46-Ubuntu SMP Wed Jul 8 07:21:34 UTC 2009 i686 GNU/Linux 
$ ulimit -s 
8192 
1

的Windows(我认为Linux的),无论在大栈模型假设工作,也就是说,有一个堆栈(每个线程),其空间线程开始之前进行了预分配。 我怀疑操作系统只是将预先分配的大小的虚拟内存空间分配给该堆栈区域,并且随着堆栈的末端超出页边界而添加下面的实际内存页面,直到达到上限(“ulimit”).ck由于操作系统经常将堆栈远离其他结构,因此当达到ulimit时,操作系统可能能够扩展堆栈,如果发生溢出时没有其他东西显示在堆栈旁边,就可能会扩展堆栈。一般来说,如果你正在构建一个足够大的程序复合体来溢出堆栈,你可能会动态地分配内存,并且没有人认为堆栈旁边的区域没有被分配。如果分配了这样的内存,操作系统当然不能扩展堆栈。

这意味着应用程序无法指望操作系统自动扩展的堆栈。实际上,堆栈不能增长。

理论上,一个耗尽堆栈的应用程序可能会启动一个更大堆栈的新线程,复制现有的堆栈并继续,但实际上我怀疑这是可以做到的,如果除了指针之外没有别的原因到局部变量堆栈将需要调整和C/C++编译器不能找到这样的指针并调整它们。 结果:ulimit必须在程序启动之前声明,并且一旦超过,程序就会死亡。

如果您想要一个可以任意扩展的堆栈,最好切换到使用堆分配激活记录的语言。然后,只需在地址空间用完之前不要耗尽。 32或64位虚拟机空间确保您可以使用此技术进行大量递归。

我们有一种名为PARLANSE的并行编程语言,它可以堆分配,以使成千上万的并行计算粒度(实际上)能够以这种方式任意递归。