深入C語言記憶體區域分配 程序的各個段 詳解

2021-07-07 07:52:47 字數 2715 閱讀 7581

一般情況下,乙個可執行二進位制程式(更確切的說,在linux作業系統下為乙個程序單元,在uc/osii中被稱為任務)在儲存(沒有調入到記憶體執行)時擁有3個部分,分別是**段(text)、資料段(data)和bss段。這3個部分一起組成了該可執行程式的檔案

c語言可執行**結構

名稱內容

**段可執行**、字串常量

資料段已初始化全域性變數、已初始化全域性靜態變數、區域性靜態變數、常量資料

bss段未初始化全域性變數,未初始化全域性靜態變數

區域性變數、函式引數

動態記憶體分配

(1)**段(text segment):存放cpu執行的機器指令。通常**段是可共享的,這使得需要頻繁被執行的程式只需要在記憶體中擁有乙份拷貝即可。**段也通常是唯讀的,這樣可以防止其他程式意外地修改其指令。另外,**段還規劃了區域性資料所申請的記憶體空間資訊。

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

(2)資料段(data segment):或稱全域性初始化資料段/靜態資料段(initialized data segment/data segment)。該段包含了在程式中明確被初始化的全域性變數、靜態變數(包括全域性靜態變數和區域性靜態變數)和常量資料。

(3)未初始化資料段:亦稱bss(block started by symbol)。該段存入的是全域性未初始化變數、靜態未初始化變數。

而當程式被載入到記憶體單元時,則需要另外兩個域:堆域和棧域。

(4)棧段(stack):存放函式的引數值、區域性變數的值,以及在進行任務切換時存放當前任務的上下文內容。

(5)堆段(heap):用於動態記憶體分配,即使用malloc/free系列函式來管理的記憶體空間。

在將應用程式載入到記憶體空間執行時,作業系統負責**段、資料段和bss段的載入,並將在記憶體中為這些段分配空間。棧段亦由作業系統分配和管理,而不需要程式設計師顯示地管理;堆段由程式設計師自己管理,即顯示地申請和釋放空間。

另外,可執行程式在執行時具有相應的程式屬性。在有作業系統支援時,這些屬性頁由作業系統管理和維護。

下面給出示例程式**,注釋已經在**中寫明:

/***段、資料段和bss段儲存變數型別*/

#include

const int    g_a       = 10;            //資料段

int            g_b       = 20;            //資料段

static int    g_c       = 30;            //資料段

static int    g_d;                    //bss段

int            g_e;                    //bss段

char        *p1;                    //bss段

void main( )

放在常量區,編譯器可能會將它與p3所指向 的"123456"優化成一塊

printf("\n");

printf( "**段,全域性初始化變數, 唯讀const,  g_a,     addr:0x%08x\n", &g_a);

printf("\n");

printf( "資料段,全域性變數,       初始化      g_b,     addr:0x%08x\n", &g_b);

printf( "資料段,靜態全域性變數,   初始化,     g_c,     addr:0x%08x\n", &g_c);

printf("\n");

printf( "bss段, 全域性變數,       未初始化    g_e,     addr:0x%08x\n", &g_e, g_e );    

printf( "bss段, 靜態全域性變數,   未初始化,   g_d,     addr:0x%08x\n", &g_d );

printf( "bss段, 靜態區域性變數,   初始化,     local_c, addr:0x%08x\n", &local_c);

printf( "bss段, 靜態區域性變數,   未初始化,   local_d, addr:0x%08x\n", &local_d);

printf("\n");

printf( "棧,    區域性變數,                   local_a, addr:0x%08x\n", &local_a );

printf("\n");

printf( "堆,    malloc分配記憶體,             p1,      addr:0x%08x\n", p1 );

}

C語言中的記憶體分配深入 二

int p a,b p a p b 即便是ab都沒有分配值,但是它的位址是存在的 第二 上面的那種情況是有侷限性的,他的成立條件就是系統已經給這個指標分配好4個位元組的情況,因此,也並不是所有的指標都可以任意指向,當乙個指標以另外乙個物件的指標的形式存在的時候,指標的4個位元組是確定的了,同情況一,...

C 五種記憶體分配區域

變數的記憶體空間主要有以下幾個 堆 heap 棧 stack 全域性靜態區 常量區 區 heap 不連續的記憶體區域,由開發者自行進行開闢和釋放。如果程式結束時沒有進行釋放 作業系統會對其進行管理。開發者通過new malloc等建立存放在heap上的變數,通過delete free對他們進行刪除。...

各程式語言的記憶體分配方式

c 的記憶體分配方式 1 棧區 stack 由編譯器自動分配釋放,在不需要的時候自動清除。用於存放函式的引數 區域性變數等。在乙個程序中,位於使用者虛擬位址空間頂部的是使用者棧,編譯器用它來實現函式的呼叫。操作方式類似資料結構中的棧 後進先出 2 堆區 heap 就是那些由 new 分配的記憶體塊,...