C程序的储存空间是如何分配?
可執(zhí)行程序包括BSS段、數(shù)據(jù)段、代碼段。
在類UNIX系統(tǒng)下可使用size命令查看可執(zhí)行文件的段大小信息。如size a.out:
~/Desktop/MyC$ size a.outtext data bss dec hex filename1672 600 8 2280 8e8 a.out1.數(shù)據(jù)段存放已初始化的全局變量和靜態(tài)變量,數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配。
2.BSS段(Block Started by Symbol)存放未初始化的全局變量和靜態(tài)變量。
????????BSS段的數(shù)據(jù)是可讀寫的,鏈接器從可執(zhí)行文件中得到BSS段的大小,然后申請(qǐng)得到這塊內(nèi)存空間,這塊內(nèi)存空間緊跟在數(shù)據(jù)段的后面。由此可知BSS段并不占用可執(zhí)行文件的大小。在使用BSS段之前BSS段會(huì)自動(dòng)初始化為0。所以,未初始的全局變量和靜態(tài)變量在程序執(zhí)行之前已經(jīng)是0了。BSS段屬于靜態(tài)內(nèi)存分配。
包含數(shù)據(jù)段和BSS段的整個(gè)區(qū)段通常稱為數(shù)據(jù)區(qū)。
3.代碼段:用來(lái)存放程序的代碼內(nèi)存空間。它的大小在程序運(yùn)行前就已經(jīng)確定了,并且該區(qū)域只能讀不能寫。在代碼段中,也有可能包含了一些只讀的常數(shù)變量,例如字符串常量等。
????????代碼段和數(shù)據(jù)段在編譯時(shí)已經(jīng)分配了空間,而BSS段則在程序被調(diào)入內(nèi)存后才分配的。因此BSS段(未進(jìn)行初始化的數(shù)據(jù))的內(nèi)容并不存放在磁盤上的程序文件中。需要存放在程序文件中的只有代碼段和數(shù)據(jù)段(存放已初始化的全局變量和靜態(tài)變量)的內(nèi)容。
????????程序編譯后生成的目標(biāo)文件至少含有這三個(gè)段,這三個(gè)段的大致結(jié)構(gòu)圖如下所示:
可執(zhí)行程序在運(yùn)行時(shí)會(huì)多出兩個(gè)區(qū)域:棧區(qū)和堆區(qū)。
4.棧區(qū):由操作系統(tǒng)自動(dòng)分配和釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。每當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),該函數(shù)的返回類型和一些調(diào)用的信息也會(huì)被存放到棧中。然后這個(gè)被調(diào)用的函數(shù)再為它的自動(dòng)變量和臨時(shí)變量在棧上分配空間。每調(diào)用一個(gè)函數(shù)一個(gè)新的棧就會(huì)被使用。棧區(qū)是從高地址位向低地址位增長(zhǎng)的,是一塊連續(xù)的內(nèi)存區(qū)域,最大容量是由系統(tǒng)預(yù)先定義好的,申請(qǐng)的??臻g超過(guò)這個(gè)界限時(shí)會(huì)提示溢出,用戶能從棧中獲取的空間較小。
小知識(shí):
自動(dòng)變量:什么是自動(dòng)變量呢?自動(dòng)變量就是指在函數(shù)內(nèi)部定義使用的變量。只能在函數(shù)內(nèi)部使用它。自動(dòng)變量是局部變量,即它的作用區(qū)域是在定義它的函數(shù)內(nèi)部。由于自動(dòng)變量在定義它的函數(shù)的外部是不可見(jiàn)的,所以允許我們?cè)谶@個(gè)函數(shù)外部或者其他的函數(shù)內(nèi)部定義同名的變量。計(jì)算機(jī)在執(zhí)行這個(gè)函數(shù)的時(shí)候,創(chuàng)建這個(gè)變量并為它分配內(nèi)存,當(dāng)函數(shù)執(zhí)行完畢返回后,自動(dòng)變量就會(huì)被銷毀。為自動(dòng)變量分配內(nèi)存就是壓棧,而函數(shù)返回時(shí)就退棧。
臨時(shí)變量是指在未在程序開頭部分聲明的,待使用它時(shí)才聲明類型的變量。常見(jiàn)的如函數(shù)中定義的變量,循環(huán)語(yǔ)句、條件語(yǔ)句中聲明定義的變量。這些變量可與主程序中的變量同名,在其作用域里,主程序中的同名變量一般無(wú)法調(diào)用。并且這種變量有效存在時(shí)間是從變量聲明開始到相應(yīng)程序段(循環(huán)結(jié)構(gòu)或函數(shù)體)結(jié)束。
5.堆區(qū):用于動(dòng)態(tài)分配內(nèi)存,位于BSS和棧中間的地址區(qū)域。由程序員親自用malloc()申請(qǐng)分配和用free()釋放。堆是從低地址位向高地址位增長(zhǎng),采用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。頻繁的 malloc/free造成內(nèi)存空間的不連續(xù),產(chǎn)生碎片。當(dāng)申請(qǐng)堆空間時(shí)庫(kù)函數(shù)是按照一定的算法搜索可用的足夠大的空間。因此堆的效率比棧要低的多。
最后提示一下:內(nèi)存泄漏是指內(nèi)存分配出去以后,你再也訪問(wèn)不到了。
總結(jié)
以上是生活随笔為你收集整理的C程序的储存空间是如何分配?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java的scjp考试_Sun认证Jav
- 下一篇: 第四十九期:化繁为简的五种码农必备工具