程式在記憶體中的布局結構

2021-09-19 10:06:40 字數 2087 閱讀 7678

**:並根據自己的理解做了整理

參考:bss段:(bss segment)通常是指用來存放程式中未初始化的全域性變數的一塊記憶體區域。bss是英文block started by symbol的簡稱。bss段屬於靜態記憶體分配。【儲存全域性未初始化的變數】

資料段:資料段(data segment)通常是指用來存放程式中 已初始化 的 全域性變數 的一塊記憶體區域。資料段屬於靜態記憶體分配。 【儲存全域性已初始化的變數】

**段:**段(code segment/text segment)通常是指用來存放 程式執行** 的一塊記憶體區域。這部分區域的大小在程式執行前就已經確定,並且記憶體區域通常屬於 唯讀 , 某些架構也允許**段為可寫,即允許修改程式。在**段中,也有可能包含一些 唯讀的常數變數 ,例如字串常量等。程式段為程式**在記憶體中的對映.乙個程式可以在記憶體中多有個副本.【儲存的是二進位制後的程式**】

堆(heap):堆是用於存放程序執行中被動態分配的記憶體段,它的大小並不固定,可動態擴張或縮減。當程序呼叫malloc/free等函式分配記憶體時,新分配的記憶體就被動態新增到堆上(堆被擴張)/釋放的記憶體從堆中被剔除(堆被縮減)【儲存初始化的區域性變數】

棧(stack):棧又稱堆疊, 存放程式的 區域性變數 (但不包括static宣告的變數, static 意味著 在資料段中 存放變數)。除此以外,在函式被呼叫時,棧用來傳遞引數和返回值。由於棧的先進先出特點,所以棧特別方便用來儲存/恢復呼叫現場。儲動態記憶體分配,需要程式設計師手工分配,手工釋放【儲存的動態未初始化變數】

下圖是apue中的乙個典型c記憶體空間分布圖

【堆向高記憶體位址生長,棧向低記憶體位址生長,參考】

【linux下可以通過cat /proc/程序號/maps檢視程式在記憶體中的分配,參考

在作業系統中,乙個程序就是處於執行期的程式(當然包括系統資源),實際上正在執行的程式**的活標本。那麼程序的邏輯位址空間是如何劃分的呢?

引用:圖1做了簡單的說明(linux系統下的)

左邊的是unix/linux系統的執行檔案,右邊是對應程序邏輯位址空間的劃分情況。

首先是堆疊區(stack),堆疊是由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。棧的申請是由系統自動分配,如在函式內部申請乙個區域性變數 int h,同時判別所申請空間是否小於棧的剩餘空間,如若小於的話,在堆疊中為其開闢空間,為程式提供記憶體,否則將報異常提示棧溢位。    

其次是堆(heap),堆一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由os** 。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶。堆的申請是由程式設計師自己來操作的,在c中使用malloc函式,而c++中使用new運算子,但是堆的申請過程比較複雜:當系統收到程式的申請時,會遍歷記錄空閒記憶體位址的鍊錶,以求尋找第乙個空間大於所申請空間的堆結點,然後將該結點從空閒結點鍊錶中刪除,並將該結點的空間分配給程式,此處應該注意的是有些情況下,新申請的記憶體塊的首位址記錄本次分配的記憶體塊大小,這樣在delete尤其是delete時就能正確的釋放記憶體空間。

接著是全域性資料區(靜態區) (static),全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域, 未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。 另外文字常量區,常量字串就是放在這裡,程式結束後有系統釋放。

最後是程式**區,放著函式體的二進位制**。

舉例說明一下:

int a = 0;                   //全域性初始化區 

char *p1;                //全域性未初始化區 

int main() 

程式在記憶體中的布局

c語言程式在記憶體中的分布 段 text 存放著程式的機器碼和唯讀資料 常量 全域性區 靜態區 由編譯器編譯時分配,程式執行結束後釋放 屬於靜態記憶體分配 在程式的二進位制檔案中,bss段不佔儲存空間,只有在載入到記憶體中才分配 data段 存放已初始化的靜態變數 static 修飾 和全域性變數 ...

C程式在記憶體中的布局

程式在記憶體中的分布 程式執行後在記憶體中分為4部分 區,資料區,堆區和棧區 源 已初始化的變數 未初始化的變數 堆空間 棧空間 命令列引數和環境變數 記憶體空間主要是堆疊 堆從低位址向高位址增長 棧從高位址向低位址增長。棧空間是靜態的儲存空間 函式的引數,函式的區域性變數儲存在棧區,函式呼叫時,需...

linux 程序在記憶體中的布局

先從 linux平台下 虛擬記憶體管理說起,寫c程式時,我們經常會列印乙個指標位址,說這個指標指向某某記憶體位址.可這些位址是真實物理記憶體位址嗎?不是 這些只是虛擬記憶體位址.當乙個c程式調入記憶體開始執行後,在記憶體中就會產生乙個程序.而在多工作業系統中每個程序都擁有一片屬於自己的記憶體空間 記...