[轉]程式碼段(codesegment/textsegment)、資料段(datasegment)、bss段(bsssegment)、rodata段、棧(stack)、堆(heap)
阿新 • • 發佈:2020-10-23
【轉自】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”優化成一個地方 }