[轉]深入C語言內存區域分配(進程的各個段)詳解
阿新 • • 發佈:2018-01-21
str 一個 以及 修改 參數 ext 分區 指令 上下文
存放CPU執行的機器指令。通常代碼段是可共享的,這使得需要頻繁被執行的程序只需要在內存中擁有一份拷貝即可。代碼段也通常是只讀的,這樣可以防止其他程序意外地修改其指令。另外,代碼段還規劃了局部數據所申請的內存空間信息。
代碼段(code segment/text segment)通常是指用來存放程序執行代碼的一塊內存區域。這部分區域的大小在程序運行前就已經確定,並且內存區域通常屬於只讀, 某些架構也允許代碼段為可寫,即允許修改程序。在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。
一般情況下,一個可執行二進制程序(更確切的說,在Linux操作系統下為一個進程單元,在UC/OSII中被稱為任務)在存儲(沒有調入到內存運行)時擁有3個部分,分別是代碼段(text)、數據段(data)和BSS段。這3個部分一起組成了該可執行程序的文件
C語言可執行代碼結構
名稱 | 內容 |
代碼段 | 可執行代碼、字符串常量 |
數據段 | 已初始化全局變量、已初始化全局靜態變量、局部靜態變量、常量數據 |
BSS段 | 未初始化全局變量,未初始化全局靜態變量 |
棧 | 局部變量、函數參數 |
堆 | 動態內存分配 |
(1)代碼段(text segment):
代碼段(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 <stdio.h> 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( ) { int local_A; //棧 static int local_C = 0; //數據段 static int local_D; //數據段 char *p3 = "123456"; //123456在代碼段,p3在棧上 p1 = (char *)malloc( 10 ); //堆,分配得來得10字節的區域在堆區 strcpy( p1, "123456" ); //123456{post.content}放在常量區,編譯器可能會將它與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語言內存區域分配(進程的各個段)詳解