linux 下 C 程式 程序 記憶體布局

2021-06-06 12:57:25 字數 869 閱讀 4115

記憶體對映段、堆的起始位址加上隨機的偏移量來打亂布局。不幸的是,32 位位址空間相當緊湊,給隨機化所留下的空當不大,削弱了這種技巧的效果

。程序位址空間中最頂部的段是棧,大多數程式語言將之用於儲存區域性變數和函式引數。呼叫乙個方法或函式會將乙個新的棧楨(stack frame)壓入棧中。棧楨在函式返回時被清理。也許是因為資料嚴格的遵從lifo的順序,這個簡單的設計意味著不必使用複雜的資料結構來追蹤棧的內容,只需要乙個簡單的指標指向棧的頂端即可。因此壓棧(pushing)和退棧(popping)過程非常迅速、準確。另外,持續的重用棧空間有助於使活躍的棧記憶體保持在cpu快取中

,從而加速訪問。程序中的每乙個執行緒都有屬於自己的棧。

通過不斷向棧中壓入的資料,超出其容量就有會耗盡棧所對應的記憶體區域。這將觸發乙個頁故障(page fault),並被 linux 的expand_stack()處理,它會呼叫acct_stack_growth()來檢查是否還有合適的地方用於棧的增長。如果棧的大小低於rlimit_stack(通常是8mb),那麼一般情況下棧會被加長,程式繼續愉快的執行,感覺不到發生了什麼事情。這是一種將棧擴充套件至所需大小的常規機制。然而,如果達到了最大的棧空間大小,就會棧溢位(stack overflow),程式收到乙個段錯誤(segmentation fault)。當映**的棧區域擴充套件到所需的大小後,它就不會再收縮回去,即使棧不那麼滿了。這就好比聯邦預算,它總是在增長的。

動態棧增長是唯一一種訪問未對映記憶體區域(圖中白色區域)而被允許的情形。其它任何對未對映記憶體區域的訪問都會觸發頁故障,從而導致段錯誤。一些被對映的區域是唯讀的,因此企圖寫這些區域也會導致段錯誤。

在棧的下方,是我們的記憶體對映段。此處,核心將檔案的內容直接對映到記憶體。任何應用程式都可以通過 linux 的 mmap() 系統呼叫(實現

特殊目的分配器

Linux程序的記憶體布局

這張圖很好,注意其中最上面是高位位址,雖然很多個0,但是c開頭的,不要看反了 更具體的可以看這裡 a.正文段。這是由cpu執行的機器指令部分。通常,正文段是可共享的,所以即使是經常執行的程式 如文字編輯程式 c編譯程式 shell等 在儲存器中也只需要有乙個副本,另外,正文段常常是唯讀的,以防止程式...

C 記憶體布局(下)

虛繼承解決了從不同途徑繼承的類具有共同基類的問題,使得共同基類只有乙份拷貝。解決了二義性的問題,也節省了記憶體。虛繼承的一般類圖如下所示 sizeof derived 40 位元組。經過分析,可以得到derived類在記憶體中的儲存結構示意圖為 各部分在記憶體中的存放順序為先父類 後子類 最後公共基...

C程式記憶體布局

對於初學c語言學者,理解c程記憶體布局對於我們理解與運用指標非常重要,在筆試中也經常有考題涉及到。以下測試在虛擬機器ubuntu18.04下的測試結果,在樹莓派 arm處理器 測試不同之處也會指出。1.程式各段記憶體遵循上圖順序記憶體布局 結果如下圖 把位址在圖上標出 圖中最低位址和最高位址只是表明...