c語言可執行**結構
名稱內容
**段可執行**、字串常量
資料段已初始化全域性變數、已初始化全域性靜態變數、區域性靜態變數、常量資料
bss段
未初始化全域性變數,未初始化全域性靜態變數
棧區域性變數、函式引數
堆動態記憶體分配
一般情況下,乙個可執行二進位制程式(更確切的說,在linux作業系統下為乙個程序單元,在uc/osii中被稱為任務)在儲存(沒有調入到記憶體執行)時擁有3個部分,分別是**段(text)、資料段(data)和bss段。這3個部分一起組成了該可執行程式的檔案。
(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段的載入,並將在記憶體中為這些段分配空間。棧段亦由作業系統分配和管理,而不需要程式設計師顯示地管理;堆段由程式設計師自己管理,即顯示地申請和釋放空間。
另外,可執行程式在執行時具有相應的程式屬性。在有作業系統支援時,這些屬性頁由作業系統管理和維護。
下面給出示例程式**,注釋已經在**中寫明:
[cpp]
view plain
copy
print?
/***段、資料段和bss段儲存變數型別*/
#include
const
intg_a = 10;
//**段
intg_b = 20;
//資料段
static
intg_c = 30;
//資料段
static
intg_d;
//bss段
intg_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/c++編譯的程式占用的記憶體分為以下幾個部分
1、棧區(stack)— 由
編譯器自動分配釋放
,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。
2、堆區(heap) —
一般由程式設計師分配釋放
, 若程式設計師不釋放,程式結束時可能由os** 。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶,呵呵。
3、全域性區(靜態區)(static)—,全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域, 未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。 - 程式結束後有系統釋放
4、文字常量區 —常量字串就是放在這裡的。 程式結束後由系統釋放
5、程式**區—存放函式體的二進位制**。
乙個正常的程式在記憶體中通常分為程式段,資料端和堆疊三部分。
程式段裡放著程式的機器碼和唯讀資料,這個段通常是唯讀
,對它的寫操作是非法的。
資料段放的是程式中的靜態資料
。動態資料則通過堆疊來存放
。在記憶體中,它們的位置如下:
+------------------+ 記憶體低端
| 程式段 |
|------------------|
| 資料段 |
|------------------|
| 堆 棧 |
+------------------+ 記憶體高階
**段,唯讀資料段(常量,字面值,const宣告的變數),已初始化可讀寫資料段(已初始化靜態和全域性變數),未初始化可讀寫資料段(未初始化靜態和全域性變數),棧,堆
c 記憶體分配詳解
一 c c 記憶體分配的5個區分別是 棧區 堆區 全域性區 靜態區 文字常量區 程式 區 1 棧區 編輯器自動分配 和 釋放,存放函式的引數,區域性變數等。2 堆區 一般是程式設計師分配和釋放,如果在程式一直執行的狀態下,程式設計師不去釋放記憶體,會導致記憶體洩漏之後會打到一定程度的時候會導致系統崩...
C 中記憶體分配詳解
程式執行時,特別要注意的是記憶體的分配。下面介紹c 程式設計中的記憶體分配。一 記憶體基本構成 可程式設計內存在基本上分為這樣的幾大部分 靜態儲存區 堆區和棧區。他們的功能不同,對他們使用方式也就不同。靜態儲存區 內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在。它主要存放靜態資...
C 程式記憶體分配詳解
1.硬碟中的結構 程式 首先在linux下檢視一下test檔案的資訊 root localhost ctest file test 此檔案基本情況 test elf 32 bit lsb executable,intel 80386,version 1 sysv for gnu linux 2.2....