天天看點

C_CPP程序記憶體空間分布

C_CPP程式記憶體空間分布

記憶體分布分為5個部分,從高位址到低位址依次為棧區(stack),堆區(heap),未初始化資料段(uninitialized data),初始化資料段(initialize data)和代碼段(text)。

有些文檔也把初始化的資料段和未初始化的資料段合稱全局區。

1. 文本段--隻讀、共享,作業系統管理

文本段也叫代碼段,是對象檔案或記憶體中程式的一部分,其中包含可執行指令。文本段在堆棧的下面,是防止堆棧溢出覆寫它。

通常代碼段是共享的,對于經常執行的程式,隻有一個副本需要存儲在記憶體中;代碼段是隻讀的,以防止程式以外修改指令。

2. 初始化的資料段

通常稱為資料段,是程式的虛拟位址空間的一部分,它包含程式員初始化的全局變量和靜态變量以及常量,可以進一步劃分為隻讀區域和讀寫區域。

例如,c中的char=“hello world”的全局字元串,以及main(例如全局)之外的int debug=1這樣的c語句,将被存儲在初始的讀寫區域中。

而像const char字元串=“hello world”這樣的全局c語句常量字元串文字“hello world”被存儲在初始化的隻讀區域中,并在初始化的讀寫區域中存儲字元指針變量字元串。

3. 未初始化的資料段--核心初始化為0

通常稱為bss段,這個段的資料在程式開始之前有核心初始化為0,包含所有初始化為0和沒有顯示初始化的全局變量和靜态變量。

這個段在程式開始之前由核心初始化為全0,是以不在可執行檔案中占用位置,可減少可執行檔案體積。

4. 堆--程式員管理

堆是動态記憶體配置設定通常發生的部分。記憶體配置設定由低到高,配置設定方式類似于資料結構的連結清單。堆區域從bss段的末尾開始,并從那裡逐漸增加到更大的位址。

堆是由程式員自己配置設定的,或程式結束後由作業系統自動回收。堆區域由所有共享庫和程序中動态加載的子產品共享。(malloc和new從堆區配置設定記憶體)

5. 棧--編譯器配置設定管理

存放自動變量,以及函數調用時儲存的資訊。每當進行函數調用時,函數的實參和傳回位址以及調用者的上下文環境會被存放在棧中;棧區由編譯器自動配置設定,從高位址向低位址擴充。

在函數調用時,第一個進棧的是主函數中後的下一條指令(函數調用語句的下一條可執行語句)的位址,然後是函數的各個參數,在大多數的c編譯器中,參數是由右往左入棧的,然後是函數中的局部變量。注意靜态變量是不入棧的。 當本次函數調用結束後,局部變量先出棧,然後是參數,最後棧頂指針指向最開始存的位址,也就是主函數中的下一條指令,程式由該點繼續運作。

不同區域存放的資料,賦予不同的生命周期,給程式設計更大的靈活性。