乙個程式本質上都是由 bss 段、data段、text段三個組成的。可以看到乙個可執行程式在儲存(沒有調入記憶體)時分為**段、資料區和未初始化資料區三部分。
程式編譯後生成的目標檔案至少含有這三個段,這三個段的大致結構圖如下所示:
text段和data段在編譯時已經分配了空間,而bss段並不占用可執行檔案的大小,它是由鏈結器來獲取記憶體的。
bss段(未進行初始化的資料)的內容並不存放在磁碟上的程式檔案中。其原因是核心在程式開始執行前將它們設定為0。需要存放在程式檔案中的只有正文段和初始化資料段。
data段(已經初始化的資料)則為資料分配空間,資料儲存到目標檔案中。
資料段包含經過初始化的全域性變數以及它們的值。bss段的大小從可執行檔案中得到,然後鏈結器得到這個大小的記憶體塊,緊跟在資料段的後面。當這個記憶體進入程式的位址空間後全部清零。包含資料段和bss段的整個區段此時通常稱為資料區。
可執行程式在執行時又多出兩個區域:棧區和堆區。
(4)棧區:由編譯器自動釋放,存放函式的引數值、區域性變數等。每當乙個函式被呼叫時,該函式的返回型別和一些呼叫的資訊被存放到棧中。然後這個被呼叫的
函式再為他的自動變數和臨時變數在棧上分配空間。每呼叫乙個函式乙個新的棧就會被使用。棧區是從高位址位向低位址位增長的,是一塊連續的記憶體區域,最大容
量是由系統預先定義好的,申請的棧空間超過這個界限時會提示溢位,使用者能從棧中獲取的空間較小。
(5)堆區:用於動態分配記憶體,位於bss和棧中間的位址區域。由程式設計師申請分配和釋放。堆是從低位址位向高位址位增長,採用鏈式儲存結構。頻繁的
malloc/free造成記憶體空間的不連續,產生碎片。當申請堆空間時庫函式是按照一定的演算法搜尋可用的足夠大的空間。因此堆的效率比棧要低的多。
下圖將體現c的原始檔對應儲存空間:
此時程式還沒有被放入記憶體,只是在硬碟儲存的情況,此時bss並未占用空間。bss在鏈結的時候被獲得記憶體空間。
下圖表示程式執行,即程式在記憶體時的儲存布局:
全域性初始化區
char *p1; //
全域性未初始化區
main()
Linux下C程式的儲存空間布局
下面是對可執行檔案aa執行size命令後得到的結果。root 1 algriom size aa text data bss dec hex filename 1257 500 16 1773 6ed aa 其中 text 表示正文段大小,這是cpu執行的機器指令部分,通常,正文段是可共享的,所以即...
Linux下C程式的儲存空間布局
下面是對可執行檔案aa執行size命令後得到的結果。root 1 algriom size aa text data bss dec hex filename 1257 500 16 1773 6ed aa 其中 text 表示正文段大小,這是cpu執行的機器指令部分,通常,正文段是可共享的,所以即...
Linux下C程式的儲存空間布局
在elf格式的可執行檔案中,全域性記憶體包括三種 bss data和rodata。其它可執行檔案格式與之類似。了解了這三種資料的特點,我們才能充分發揮它們的長處,達到速度與空間的最優化。1 bss block started by symbol bss是指那些沒有初始化的和初始化為0的全域性變數和靜...