程式碼段/資料段/堆疊段
BSS段:BSS段(bss segment)通常是指用來存放程式中未初始化的全域性變數的一塊記憶體區域,或者全域性變數初始化等於0的。
BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態記憶體分配。
資料段:資料段(data segment)通常是指用來存放程式中已初始化的全域性變數的一塊記憶體區域。
資料段屬於靜態記憶體分配(rodata(只讀資料段))。
程式碼段:程式碼段(code segment/text segment)通常是指用來存放程式執行程式碼的一塊記憶體區
域。這部分割槽域的大小在程式執行前就已經確定,並且記憶體區域通常屬於讀, 某些架構
也允許程式碼段為可寫,即允許修改程式。在程式碼段中,也有可能包含一些只讀的常數變數
,例如字串常量等。
注意程式碼段通常是隻讀,const int a 這樣的常量是放在資料段。
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
unsigned char a;
short b;
short c:5;
short d:7;
short e:6;
long f;
char **g;
unsigned char h[5];
} MyStruct;
const MyStruct VarA ={0};
char *p="test";
MyStruct VarB={0};
int main()
{
MyStruct *VarA;
MyStruct VarB,VarC[3];
const char *p1="test";
VarA=(MyStruct *)malloc(sizeof(MyStruct));
VarB.a=12;
printf("%d\n",sizeof(VarA));
printf("%d\n",sizeof(VarB));
printf("%d\n",::VarB.a);
return 0;
}
前面打兩點表示是全域性變數。
::VarA 放在ROM資料段
VarA放在棧中
*VarA 放在堆中
待完善
rodata的意義同樣明顯,ro代表read only,即只讀資料(const)。關於rodata型別的資料,要注意以下幾點:
l 常量不一定就放在rodata裡,有的立即數直接編碼在指令裡,存放在程式碼段(.text)中。
l 對於字串常量,編譯器會自動去掉重複的字串,保證一個字串在一個可執行檔案(EXE/SO)中只存在一份拷貝。
l rodata
l 在有的嵌入式系統中,rodata放在ROM(如norflash)裡,執行時直接讀取ROM記憶體,無需要載入到RAM記憶體中。
l 在嵌入式linux系統中,通過一種叫作XIP(就地執行)的技術,也可以直接讀取,而無需要載入到RAM記憶體中。
由此可見,把在執行過程中不會改變的資料設為rodata型別的,是有很多好處的:在多個程序間共享,可以大大提高空間利用率,甚至不佔用RAM空間。同時由於rodata在只讀的記憶體頁面(page)中,是受保護的,任何試圖對它的修改都會被及時發現,這可以幫助提高程式的穩定性