Linux進程的虛擬內存區域分為:代碼區、只讀常量區、全局區、BSS段、堆區、棧區
代碼區:存儲功能代碼,函數名所在的區域
只讀常量區:存放字符串常量,以及const修飾的全局變量
全局區/數據區:存放已經初始化的全局變量和已經初始化用static修飾的局部變量
BSS段:存放沒有初始化的全局變量和未初始化靜態局部變量,該區域會在main函數執行前進行自動清零
堆區:使用malloc/new free/delete函數處理的內存,該區域的內存需要程序員手動申請和釋放
棧區:存放局部變量(包括函數的形參),const修飾的局部變量以及塊變量,該區域的內存由操作系統負責分配和回收,程序員盡管放心使用
注意:棧區和堆區之間並沒有嚴格分割線,可以進行微調,並且堆區分配一般從低地址到高地址分配,而棧區分配一般從高地址到低地址分配
可以通過以下代碼來驗證以上Linux進程的虛擬內存區域划分
//進程中內存區域的划分 #include <stdio.h> #include <stdlib.h> #include <string.h> int i1 = 10; //全局區 int i2 = 20; //全局區 int i3; //BSS段 const int i4 = 40;//只讀常量區 void fn(int i5) //棧區 { int i6 = 60;//棧區 static int i7 = 70;//全局區 const int i8 = 80; //棧區 int* p1 = (int*)malloc(sizeof(int));//堆區 int* p2 = (int*)malloc(sizeof(int));//堆區 char* str = "good";//只讀常量區 char strs[] = "good";//棧區 printf("只讀常量區:&i4 = %p\n",&i4); printf("只讀常量去:str = %p\n",str); printf("---------------------\n"); printf("全局區:&i1 = %p\n",&i1); printf("全局區:&i2 = %p\n",&i2); printf("全局區:&i7 = %p\n",&i7); printf("---------------------\n"); printf("BSS段:&i3 = %p\n",&i3); printf("---------------------\n"); printf("堆區:p1 = %p\n",p1); printf("堆區:p2 = %p\n",p2); printf("---------------------\n"); printf("棧區:&i5 = %p\n",&i5); printf("棧區:&i6 = %p\n",&i6); printf("棧區:&i8 = %p\n",&i8); printf("棧區:strs = %p\n",strs); } int main(void) { printf("代碼區:fn = %p\n",fn); printf("-----------------------\n"); fn(10); return 0; }
執行結果如下:
代碼區:fn = 0x40062d
-----------------------
只讀常量區:&i4 = 0x400884
只讀常量去:str = 0x400888
---------------------
全局區:&i1 = 0x601058
全局區:&i2 = 0x60105c
全局區:&i7 = 0x601060
---------------------
BSS段:&i3 = 0x601068
---------------------
堆區:p1 = 0x1d9b010
堆區:p2 = 0x1d9b030
---------------------
棧區:&i5 = 0x7ffd409525ec
棧區:&i6 = 0x7ffd409525f0
棧區:&i8 = 0x7ffd409525f4
棧區:strs = 0x7ffd40952610