天天看點

C程式的記憶體空間配置設定

可執行程式包括BSS段、資料段、代碼段。

在類UNIX系統下可使用size指令檢視可執行檔案的段大小資訊。如size a.out:

~/Desktop/MyC$ size a.out
   text     data      bss      dec      hex  filename
   1672      600        8     2280      8e8  a.out      

1.資料段存放已初始化的全局變量和靜态變量,資料段屬于靜态記憶體配置設定。

2.BSS段(Block Started by Symbol)存放未初始化的全局變量和靜态變量。

BSS段的資料是可讀寫的,連結器從可執行檔案中得到BSS段的大小,然後申請得到這塊記憶體空間,這塊記憶體空間緊跟在資料段的後面。由此可知BSS段并不占用可執行檔案的大小。在使用BSS段之前BSS段會自動初始化為0。是以,未初始的全局變量和靜态變量在程式執行之前已經是0了。BSS段屬于靜态記憶體配置設定。

包含資料段和BSS段的整個區段通常稱為資料區。

3.代碼段:用來存放程式的代碼記憶體空間。它的大小在程式運作前就已經确定了,并且該區域隻能讀不能寫。在代碼段中,也有可能包含了一些隻讀的常數變量,例如字元串常量等。

代碼段和資料段在編譯時已經配置設定了空間,而BSS段則在程式被調入記憶體後才配置設定的。是以BSS段(未進行初始化的資料)的内容并不存放在磁盤上的程式檔案中。需要存放在程式檔案中的隻有代碼段和資料段(存放已初始化的全局變量和靜态變量)的内容。

程式編譯後生成的目标檔案至少含有這三個段,這三個段的大緻結構圖如下所示:

C程式的記憶體空間配置設定

可執行程式在運作時會多出兩個區域:棧區和堆區。

4.棧區:由作業系統自動配置設定和釋放 ,存放函數的參數值,局部變量的值等。每當一個函數被調用時,該函數的傳回類型和一些調用的資訊也會被存放到棧中。然後這個被調用的函數再為它的自動變量和臨時變量在棧上配置設定空間。每調用一個函數一個新的棧就會被使用。棧區是從高位址位向低位址位增長的,是一塊連續的記憶體區域,最大容量是由系統預先定義好的,申請的棧空間超過這個界限時會提示溢出,使用者能從棧中擷取的空間較小。

小知識:

自動變量:什麼是自動變量呢?自動變量就是指在函數内部定義使用的變量。隻能在函數内部使用它。自動變量是局部變量,即它的作用區域是在定義它的函數内部。由于自動變量在定義它的函數的外部是不可見的,是以允許我們在這個函數外部或者其他的函數内部定義同名的變量。計算機在執行這個函數的時候,建立這個變量并為它配置設定記憶體,當函數執行完畢傳回後,自動變量就會被銷毀。為自動變量配置設定記憶體就是壓棧,而函數傳回時就退棧。

臨時變量是指在未在程式開頭部分聲明的,待使用它時才聲明類型的變量。常見的如函數中定義的變量,循環語句、條件語句中聲明定義的變量。這些變量可與主程式中的變量同名,在其作用域裡,主程式中的同名變量一般無法調用。并且這種變量有效存在時間是從變量聲明開始到相應程式段(循環結構或函數體)結束。