1. 每個進程都運行在自己私有的內存空間中(即虛擬地址空間)。在32位系統中,4GB的進程地址東健被分為用戶空間和內核空間兩個部分。用戶空間占據著0~3GB(用16進制表示為0xC0000000),而內核空間的范圍是3GB~4GB。對於一個進程而言,都會涉及3種不同的數據段,分別是代碼段、數據段和堆棧段。 代碼段:用於保存可執行文件的操作指令和程序定義的常量。為了防止代碼在運行的時候被其他進程修改,代碼段將只允許讀取,不能進行修改。多進程能夠共享相同的代碼段,即當程序被多次執行時,運行的相同程序將共享代碼段。 數據段:其位置緊接著代碼段,分為初始化數據段和未初始化數據段(也稱為BSS段)。初始化代碼段用於存放已經初始化的全局變量和程序的靜態變量,而未初始化數據段用於保存未初始化的全局變量。 堆棧段:堆棧段的堆用於存放進程中動態分配的內存地址。例如,在C語言中使用malloc函數、在C++中使用new函數分配的內存空間都將在堆中分配。當使用free函數或delete函數釋放內存時,分配的內存將從堆中刪除。棧用於保存程序中創建的臨時變量。函數調用時,傳遞的參數也將被保存在棧中。在函數調用結束後,其返回值也將保存在棧中。棧具有先進先出的特點,適用於保存和恢復現場。可以將棧看作用於存放臨時數據、進行數據交換的內存區域。棧的大小受操作系統的限制,因此從棧中獲得的空間大小有限,而堆的大小只是受限於虛擬內存空間,因此使用堆可以獲得較大的內存空間。堆的位置與數據段相鄰。 2. 代碼 復制代碼 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 6 int etext,edata,end;// 7 8 //g_pstr和g_buffer都為全局變量,只是一個初始化,一個未初始化 9 char *g_pstr="Global string\n"; 10 char g_buffer[20]; 11 12 inline void disp_addr(char * p,int addr) 13 { 14 printf("Name :%s Address :%0x\n",p,addr); 15 } 16 17 void disp_var(char* p) 18 { 19 char *buffer1; 20 disp_addr("buffer1 address:",(int)(&buffer1)); 21 buffer1=(char*)malloc(strlen(p)+1); 22 strcpy(buffer1,p); 23 printf("buffer1 : %s\n",buffer1); 24 free(buffer1); 25 } 26 27 int main() 28 { 29 int i=0; 30 31 //以十六進制顯示 32 printf("Addr etext :%p\n",&etext); 33 printf("Addr edata :%p\n",&edata); 34 printf("Addr end :%p\n",&end); 35 36 //顯示各個函數和變量地址 37 disp_addr(" function main() :",(int)(main)); 38 disp_addr("function disp_var():",(int)(disp_var)); 39 disp_addr(" g_pstr address :",(int)(&g_pstr)); 40 disp_addr(" g_buffer address :",(int)(&g_buffer)); 41 disp_addr(" i address :",(int)(&i)); 42 43 disp_var(g_pstr); 44 return 0; 45 } 復制代碼 3. 運行結果 復制代碼 Addr etext :0x8049954 Addr edata :0x8049958 Addr end :0x8049950 Name : function main() :,Address :804850c Name :function disp_var():,Address :80484a7 Name : g_pstr address :,Address :8049930 Name : g_buffer address :,Address :804993c Name : i address :,Address :bf8583ec Name :buffer1 address:,Address :bf8583bc buffer1 : Global string