2009-11-22 63 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的並行編程語言,它可以堆分配,以使成千上萬的並行計算粒度(實際上)能夠以這種方式任意遞歸。