代碼段(codesegment/textsegment)、數據段(datasegment)、bss段(bsssegment)、rodata段、棧(stack)、堆(heap)

原文連接: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」優化成一個地方
}
相關文章
相關標籤/搜索