1.代碼段(code或text)
代碼段由各個函數產生,函數的每一個語句將最終經過編繹和匯編生成二進制機器代碼(具體生生哪種體系結構的機器代碼由編譯器決定)。這部分區域的大小在程序運行前就已經確定,並且內存區域通常屬於只讀, 某些架構也允許代碼段為可寫,即允許修改程序。在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。
2.只讀數據段(RO Data)
只讀數據段的特點是在運行中不需要改變。只讀全局變量,只讀局部變量,程序中使用的常量(const)等會在編譯時被放入到只讀數據區。
3.讀寫數據段(RW Data)
讀寫數據段又稱已初始化數據段,表示可以讀也可以寫的數據區。通常已初始化的全局變量和局部靜態變量被放在了讀寫數據段,如:在函數中定義static char b[ 100]={“ABCDEFG”};讀寫數據區的特點是必須在程序經過初始化,如果只定義,沒初始值,則不會生成讀寫數據區,而會定位為未初始化數據區(BSS)。
4. 未初始化數據段(BSS:Block Started by Symbol)
通常是指用來存放程序中未初始化的全局變量的一塊內存區域。屬於靜態內存分配,不是目標文件中的一段。BSS段並不給該段的數據分配空間,只是記錄數據所需空間的大小。
5.堆(heap)
堆內存只在程序運行時出現,一般由程序員分配和釋放(malloc free、new delete)。它的大小並不固定,可動態擴張或縮減。分配內存的函數所分配的內存空間在堆上,程序必須保證使用free釋放,否則會發生內存洩漏。
6.棧(stack)
棧內存只在程序運行時出現,在函數內部使用的變量、函數的參數以及返回值將使用棧空間,不包括static聲明的變量。棧空間由編譯器自動分配和釋放。由於棧的先進後出特點,所以棧特別方便用來保存/恢復調用現場。從這個意義上講,我們可以把堆棧看成一個寄存、交換臨時數據的內存區。
再縷一縷:
1.全局的未初始化變量存在於BSS段中,具體體現為一個占位符;全局的已初始化變量存於Data段中
2.代碼段、RO Data、RW Data及BSS這四個段都屬於程序中的靜態區域,堆和棧屬於程序的動態區域
3.經過編譯連接生產的二進制可執行代碼,只包含代碼段、RO Data、RW Data,BSS中的數據將會在運行前置0,在程序運行後才會包含堆和棧
Example:
1 int a = 0; //全局初始化區 rw data段 2 static int b=20; //全局初始化區 rw data段 3 char *p1; //全局未初始化區 bss段 4 const int A = 10; //ro data段 5 6 void main(void) 7 { 8 int b; //棧 9 char s[] = "abc"; //棧 10 char *p2; //棧 11 static int c = 0; //全局(靜態)初始化區 rw data段 12 char *p3 = "123456"; //123456\0在ro data,p3在棧上。 13 p1 = (char*) malloc(10);//分配得來的10和20個字節的區域就在堆區 14 p2 = (char*) malloc(20); 15 strcpy(p1, "123456"); //123456\0在常量區,編譯器可能會將它與p3所指向的"123456"優化成一個地方 16 17 18 free(p1); 19 free(p2); 20 }
最後,元旦快樂~!