1. 程式人生 > >幾個常見的資料儲存區

幾個常見的資料儲存區

,就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變數的儲存區。裡面的變數通常是區域性變數、函式引數等。在一個程序中,位於使用者虛擬地址空間頂部的是使用者棧,編譯器用它來實現函式的呼叫。棧區大小固定,一般為1M,地址向下擴充套件。(由於這一特性,柔性陣列(即初始化時只指定首地址,不指定長度的陣列,初始化方式為:int a[],int a[0],int a[]={};int  b[0][5], int b[][5]={},int b[][5]等,詳見https://www.cnblogs.com/veis/p/7073076.html)無法在main函式內定義,同樣,大的動態陣列也最好不要在main函式內定義)

typedef struct _SoftArray{
	int len;
	int array[];//柔性陣列定義為結構體變數,合法
}SoftArray;
int test_static[];//柔性陣列定義為全域性變數,合法
int main()
{
    int test_main[];//柔性陣列定義為動態變數,非法
}

,指由malloc分配,free釋放,或者由new分配,delete釋放的記憶體區域,這片區域他們的釋放編譯器不去管,由我們的應用程式去控制,一般一個 new 就要對應一個 delete。如果程式設計師沒有釋放掉,那麼在程式結束後,作業系統會自動回收。堆可以動態地擴充套件和收縮,這個區域通常較大,並向高地址擴充套件。此種說法的假設是new/delete就是由malloc/free實現。

另有一種說法:由malloc分配,free釋放的儲存在堆區,由new分配,delete釋放的儲存在自由儲存區,自由儲存區一般來講不僅包括堆區,還可能包括全域性儲存區的未分配部分。

全域性/靜態儲存區,全域性變數和靜態變數被分配到同一塊記憶體中,在以前的 C 語言中,全域性變數又分為初始化的和未初始化的(初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數與靜態變數在相鄰的另一塊區域,同時未被初始化的物件儲存區可以通過 void* 來訪問和操縱,程式結束後由系統自行釋放),在 C++ 裡面沒有這個區分了,他們共同佔用同一塊記憶體區。

常量儲存區,這是一塊比較特殊的儲存區,他們裡面存放的是常量,不允許修改(當然,你要通過非正當手段也可以修改,而且方法很多),常量儲存區屬於程式碼段。程式碼段屬於應用層的劃分,劃分圖如下:

c語言記憶體分配圖

BSS段,通常是指用來存放程式中未初始化的全域性變數的一塊記憶體區域。BSS是英文Block Started by Symbol的簡稱。一般在初始化時bss 段部分將會清零。bss段屬於靜態記憶體分配,即程式一開始就將其清零了。

資料段,資料段(data segment)通常是指用來存放程式中已初始化的全域性變數的一塊記憶體區域。資料段屬於靜態記憶體分配。

程式碼段,程式碼段(code segment/text segment)通常是指用來存放程式執行程式碼的一塊記憶體區域。這部分割槽域的大小在程式執行前就已經確定,並且記憶體區域通常屬於只讀, 某些架構也允許程式碼段為可寫,即允許修改程式。在程式碼段中,也有可能包含一些只讀的常數變數,例如字串常量等。程式碼段是存放了程式程式碼的資料,假如機器中有數個程序執行相同的一個程式,那麼它們就可以使用同一個程式碼段。