C語言記憶體空間分布詳解

2021-08-26 23:20:27 字數 2012 閱讀 8101

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

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

**段: **段(code segment/text segment)通常是指用來存放程式執行**的一塊記憶體區域。這部分區域的**屬於唯讀。在**段中,字串常量也屬於這部分。

堆(heap):堆是用於存放程序執行中被動態分配的記憶體段,它的大小並不固定,可動態擴張或縮減。

棧(stack):棧又稱堆疊,存放程式的區域性變數除此以外,在函式被呼叫時,棧用來傳遞引數和返回值等。由於棧的先進先出特點,所以棧特別方便用來儲存/恢復呼叫現場。

下面圖來自unix環境高階程式設計書中:

左邊是unix/linux系統下可執行檔案內部的組織結構,右邊是可執行檔案對應到程序邏輯位址空間(即記憶體)的劃分情況。

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

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

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

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

舉例說明一下:

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

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

int main()

{ int b; // 棧

char s = 「abc」; //棧

char *p2; //棧

char *p3 = 「123456」; //123456\0在常量區,而p3在棧上

static int c =0;    //全域性(靜態)初始化區 

p1 = (char *)malloc(10);

p2 = (char *)malloc(20); //分配得來得10和20位元組的區域就在堆區

strcpy(p1, "123456"); //123456\0放在常量區,編譯器可能會將它與p3所指向的"123456"優化成乙個地方。

return 0;

1、程序位址空間

乙個程序一旦建立,就會自認為占有4g記憶體(x86_32),這個記憶體被稱作虛擬記憶體,也就是程序的位址空間。在linux下,程序位址空間的布局大致如下圖所示,其中的使用者空間大致由這些部分組成:

**段

初始化資料段

未初始化資料段 堆 棧

這些段,反映到elf格式的目標檔案(object file)中,就又可能由許多不同的節(section)組成

C語言記憶體空間分布詳解

bss段 bss segment 通常是指用來存放程式中 未初始化 的全域性變數 的一塊記憶體區域。bss是英文block started by symbol的簡稱。bss段屬於靜態記憶體分配。資料段 資料段 data segment 通常是指用來存放程式中 已初始化 的全域性變數 的一塊記憶體區域...

C 記憶體空間分布

1.stack,即棧區,存放自動變數,以及函式呼叫時儲存的資訊。每當進行函式呼叫時,函式的實參和返回位址以及呼叫者的上下文環境會被存放在棧中 棧區由編譯器自動分配,從高位址向低位址擴充套件,為什麼會這樣?我也不知道 2.heap,即堆區,動態記憶體分配都是發生在堆區,堆區由程式設計師分配釋放,或程式...

記憶體空間分布

code或.text,段 用來存放可執行的機器指令的一塊記憶體區域,這部分區域的 屬於唯讀。字串常量也在也在 段上。data,資料段 用來存放程式中已初始化的全域性變數的一塊記憶體區域,例如已初始化的全域性變數和區域性靜態變數 初始化為非0 bss 用來存放程式中未初始化的全域性變數的一塊記憶體區域...