原文連接:https://blog.csdn.net/One_L_Star/article/details/81901186
在Linux進程地址空間佈局中,從物理上,數據(user data, sys data) 和指令,都是「數據」,可是從邏輯上來說,來是有區別的,不一樣的數據,屬性不同。有些數據是指令,只讀,不可寫,有些數據可寫,有些數據只可讀,有些數據一開始就存在,有些數據,用的時候才存在,用完就沒有......架構
從邏輯層面(操做系統)把數據分紅不一樣的段(不一樣的區域)來存儲:函數
1、代碼段(codesegment/textsegment):佈局
又稱文本段,用來存放指令,運行代碼的一塊內存空間
此空間大小在代碼運行前就已經肯定
內存空間通常屬於只讀,某些架構的代碼也容許可寫
在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。
2、數據段(datasegment):優化
可讀可寫
存儲初始化的全局變量和初始化的static變量
數據段中數據的生存期是隨程序持續性(隨進程持續性)
隨進程持續性:進程建立就存在,進程死亡就消失
3、bss段(bsssegment):spa
可讀可寫
存儲未初始化的全局變量和未初始化的static變量
bss段中數據的生存期隨進程持續性
bss段中的數據通常默認爲0
4、rodata段:操作系統
只讀數據
好比printf語句中的格式字符串和開關語句的跳轉表。也就是你所說的常量區。例如,全局做用域中的 const int ival = 10,ival存放在.rodata段;再如,函數局部做用域中的printf("Hello world %d\n", c);語句中的格式字符串"Hello world %d\n",也存放在.rodata段。
5、棧(stack):.net
可讀可寫
存存儲的是函數或代碼碼中的局部變量(非static變量)
棧的生存期隨代碼塊持續性,代碼塊運行就給你分配空間,代碼塊結束,就自動回收空間
6、堆(heap):code
可讀可寫
存儲的是程序運行期間動態分配的 malloc/realloc的空間
堆的生存期隨進程持續性,從malloc/realloc 到free一直存在
blog
進程地址空間和用戶、內核的關係:進程
eg:前輩寫的一個經典例子
int a = 0; //全局初始化區 char *p1; //全局未初始化區 main() { int b; //棧 char s[] = "abc"; //棧 char *p2; //棧 char *p3 = "123456"; //123456\0在常量區,p3的棧上 static int c = 0; //全局(靜態)初始化區 p1 = (char*)malloc(10); p2 = (char*)malloc(20); //分配得來的10和20字節的區域就在堆區 strcpy(p1,"123456"); //123456\0放在常量區,編譯器可能會將它與p3所指向「123456」優化成一個地方 }