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
3
1.數據段存放已初始化的全局變量和靜態變量,數據段屬于靜態內存分配。
2.BSS段(Block Started by Symbol)存放未初始化的全局變量和靜態變量。
BSS段的數據是可讀寫的,鏈接器從可執行文件中得到BSS段的大小,然后申請得到這塊內存空間,這塊內存空間緊跟在數據段的后面。由此可知BSS段并不占用可執行文件的大小。在使用BSS段之前BSS段會自動初始化為0。所以,未初始的全局變量和靜態變量在程序執行之前已經是0了。BSS段屬于靜態內存分配。
包含數據段和BSS段的整個區段通常稱為數據區。
3.代碼段:用來存放程序的代碼內存空間。它的大小在程序運行前就已經確定了,并且該區域只能讀不能寫。在代碼段中,也有可能包含了一些只讀的常數變量,例如字符串常量等。
代碼段和數據段在編譯時已經分配了空間,而BSS段則在程序被調入內存后才分配的。因此BSS段(未進行初始化的數據)的內容并不存放在磁盤上的程序文件中。需要存放在程序文件中的只有代碼段和數據段(存放已初始化的全局變量和靜態變量)的內容。
程序編譯后生成的目標文件至少含有這三個段,這三個段的大致結構圖如下所示:
可執行程序在運行時會多出兩個區域:棧區和堆區。
4.棧區:由操作系統自動分配和釋放 ,存放函數的參數值,局部變量的值等。每當一個函數被調用時,該函數的返回類型和一些調用的信息也會被存放到棧中。然后這個被調用的函數再為它的自動變量和臨時變量在棧上分配空間。每調用一個函數一個新的棧就會被使用。棧區是從高地址位向低地址位增長的,是一塊連續的內存區域,最大容量是由系統預先定義好的,申請的棧空間超過這個界限時會提示溢出,用戶能從棧中獲取的空間較小。
小知識:
自動變量:什么是自動變量呢?自動變量就是指在函數內部定義使用的變量。只能在函數內部使用它。自動變量是局部變量,即它的作用區域是在定義它的函數內部。由于自動變量在定義它的函數的外部是不可見的,所以允許我們在這個函數外部或者其他的函數內部定義同名的變量。計算機在執行這個函數的時候,創建這個變量并為它分配內存,當函數執行完畢返回后,自動變量就會被銷毀。為自動變量分配內存就是壓棧,而函數返回時就退棧。
臨時變量是指在未在程序開頭部分聲明的,待使用它時才聲明類型的變量。常見的如函數中定義的變量,循環語句、條件語句中聲明定義的變量。這些變量可與主程序中的變量同名,在其作用域里,主程序中的同名變量一般無法調用。并且這種變量有效存在時間是從變量聲明開始到相應程序段(循環結構或函數體)結束。
5.堆區:用于動態分配內存,位于BSS和棧中間的地址區域。由程序員親自用malloc()申請分配和用free()釋放。堆是從低地址位向高地址位增長,采用鏈式存儲結構。頻繁的 malloc/free造成內存空間的不連續,產生碎片。當申請堆空間時庫函數是按照一定的算法搜索可用的足夠大的空間。因此堆的效率比棧要低的多。
最后提示一下:內存泄漏是指內存分配出去以后,你再也訪問不到了。
匯編語言
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。