2016-06-19 288 views
3

我想了解CPU在跟蹤程序堆棧/堆分配中的作用。C程序的堆棧和堆內存

閱讀一些材料,我遇到這樣的:

堆棧區域傳統上鄰接堆區域和增長的相反方向;當堆棧指針遇到堆指針時,空閒內存耗盡。

堆棧和堆指針是否存儲在程序特定的寄存器中?

如果堆棧指針指向棧頂,並且(我假設)堆棧指針指向堆棧的末尾,這些指針在不覆蓋內存(溢出)的情況​​下會如何滿足?

這在現代系統中如何工作?

+0

這是所有實現相關的。在傳統的Unix系統中,堆將從靜態存儲器的末端開始下降,並且堆棧將從地址空間的底部開始增長。但是C規範中沒有任何內容。這需要這一點,並且與現代多線程實現相比,事情並不那麼簡單。 –

+0

如果你想在*你的系統上測試這個,試着做一些測試:編寫一個程序,打印全局初始化變量的地址,全局未初始化變量,'malloc'返回的一些存儲以及一個自動堆棧)變量。看看它們如何適應地址空間。 –

回答

3

堆棧和堆指針是否存儲在特定於程序的寄存器中?

基於堆棧的體系結構(代表當前使用的絕大多數CPU)的CPU有一個特殊的堆棧指針寄存器。這是可能的,因爲堆棧本質上不會被分割。因此,一個單一的指針就足夠了。

沒有「堆指針」這樣的事情,因爲堆可能是一個零碎的數據結構。堆分配器保留一個特殊的內存片段表供分配,並在程序分配和釋放內存時進行調整。內存管理器還保存一個指向從堆中分配的最高地址的指針。

如果堆棧指針指向堆棧的頂部,和(我假設)堆指針指向堆的結束,怎麼會這些指針永遠滿足,而不會覆蓋內存(溢) ?

由於堆棧指針不能不會導致錯誤交叉,許多系統限制堆到一定數量的大小,並確保內存分配器不會讓堆的高點越過上限的堆棧。

注意:在支持併發的系統上,一次可能有多個活動的堆棧。在這種情況下,堆棧被設置爲彼此相鄰,並監視上限以檢測堆棧溢出。這裏是an article that describes techniques for detecting stack overflows

+0

堆分配器駐留在哪裏?由於它涉及程序堆,它是程序虛擬地址空間的一部分,我假設它是與虛擬內存管理器分開的東西? – wulfgarpro

+0

@wulfgarpro在具有虛擬內存堆分配器的系統上,通常位於虛擬內存管理器的頂部,從中獲取大塊,並將它們分配給各個堆內存請求。 – dasblinkenlight