1. 程式人生 > 實用技巧 >[轉]程式碼段(codesegment/textsegment)、資料段(datasegment)、bss段(bsssegment)、rodata段、棧(stack)、堆(heap)

[轉]程式碼段(codesegment/textsegment)、資料段(datasegment)、bss段(bsssegment)、rodata段、棧(stack)、堆(heap)

【轉自】https://blog.csdn.net/One_L_Star/article/details/81901186

從邏輯層面(作業系統)把資料分成不同的段(不同的區域)來儲存:

一、程式碼段(codesegment/textsegment):

  • 又稱文字段,用來存放指令,執行程式碼的一塊記憶體空間
  • 此空間大小在程式碼執行前就已經確定
  • 記憶體空間一般屬於只讀,某些架構的程式碼也允許可寫
  • 在程式碼段中,也有可能包含一些只讀的常數變數,例如字串常量等。

二、資料段(datasegment):

  • 可讀可寫
  • 儲存初始化的全域性變數和初始化的static變數
  • 資料段中資料的生存期是隨程式持續性(隨程序持續性)
    隨程序持續性:程序建立就存在,程序死亡就消失

三、bss段(bsssegment):

  • 可讀可寫
  • 儲存未初始化的全域性變數和未初始化的static變數
  • bss段中資料的生存期隨程序持續性
  • bss段中的資料一般預設為0

四、rodata段:

  • 只讀資料
  • 比如printf語句中的格式字串和開關語句的跳轉表。也就是你所說的常量區。例如,全域性作用域中的 const int ival = 10,ival存放在.rodata段;再如,函式區域性作用域中的printf("Hello world %d\n", c);語句中的格式字串"Hello world %d\n",也存放在.rodata段。

五、棧(stack):

  • 可讀可寫
  • 存儲存的是函式或程式碼碼中的區域性變數(非static變數)
  • 棧的生存期隨程式碼塊持續性,程式碼塊執行就給你分配空間,程式碼塊結束,就自動回收空間

六、堆(heap):

  • 可讀可寫
  • 儲存的是程式執行期間動態分配的 malloc/realloc的空間
  • 堆的生存期隨程序持續性,從malloc/realloc 到free一直存在

程序地址空間和使用者、核心的關係:

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”優化成一個地方
}