堆區(qū),棧區(qū),文字常量區(qū)嗽仪,全局區(qū),代碼區(qū)
棧區(qū)(stack)由編譯器自動分配釋放 ,存放方法(函數(shù))的參數(shù)值, 局部變量的值等窑业,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)钦幔,是一塊連續(xù)的內(nèi)存的區(qū)域。即棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的常柄。
堆區(qū)(heap)一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時由OS回收鲤氢,向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域西潘,從而堆獲得的空間比較靈活卷玉。
全局區(qū)(靜態(tài)區(qū))(static),全局變量和靜態(tài)變量的存儲是放在一塊 的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。程序結(jié)束后有系統(tǒng)釋放喷市。
文字常量區(qū)—常量字符串就是放在這里的相种。程序結(jié)束后由系統(tǒng)釋放。
程序代碼區(qū)—存放函數(shù)體的二進(jìn)制代碼
------
靜態(tài)存儲區(qū):內(nèi)存在程序編譯的時候就已經(jīng)分配好品姓,這塊內(nèi)存在程序的整個運行期間都存在寝并。它主要存放靜態(tài)數(shù)據(jù)、全局?jǐn)?shù)據(jù)和常量腹备。
棧區(qū):在執(zhí)行函數(shù)時衬潦,函數(shù)(包括main函數(shù))內(nèi)局部變量的存儲單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時這些存儲單元自動被釋放植酥。棧內(nèi)存分配運算內(nèi)置于處理器的指令集中镀岛,效率很高,但是分配的內(nèi)存容量有限友驮。(任何變量都處于站區(qū)漂羊,例如int a[] = {1, 2},變量a處于棧區(qū)。數(shù)組的內(nèi)容也存在于棧區(qū)卸留。)
堆區(qū):亦稱動態(tài)內(nèi)存分配走越。程序在運行的時候用malloc或new申請任意大小的內(nèi)存,程序員自己負(fù)責(zé)在適當(dāng)?shù)臅r候用free或delete釋放內(nèi)存耻瑟。動態(tài)內(nèi)存的生存期可以由我們決定买喧,如果我們不釋放內(nèi)存,程序?qū)⒃谧詈蟛裴尫诺魟討B(tài)內(nèi)存匆赃。 但是淤毛,良好的編程習(xí)慣是:如果某動態(tài)內(nèi)存不再使用,需要將其釋放掉算柳,并立即將指針置位NULL低淡,防止產(chǎn)生野指針。
------
堆棧區(qū)別:
1.管理方式不同
2.空間大小不同
3.能否產(chǎn)生碎片
4.生長方向不同
5.分配方式不同
6.分配效率不同
詳細(xì)解釋:
1.管理方式:對于棧來講,是由編譯器自動管理蔗蹋,無需我們手工控制何荚;對于堆來說,釋放工作由程序員控制猪杭,容易產(chǎn)生memory leak
2.空間大胁吞痢:一般來講在32位系統(tǒng)下,堆內(nèi)存可以達(dá)到4G的空間皂吮,從這個角度來看堆內(nèi)存幾乎是沒有什么限制的戒傻。但是對于棧來講,一般都是有一定的空間大小的蜂筹,例如需纳,在VC6下面,默認(rèn)的椧张玻空間大小是1M(好像是不翩,記不清楚了)。當(dāng)然麻裳,我們可以修改:?打開工程口蝠,依次操作菜單如下:Project->Setting->Link,在Category 中選中Output津坑,然后在Reserve中設(shè)定堆棧的最大值和commit妙蔗。 注意:reserve最小值為4Byte;commit是保留在虛擬內(nèi)存的頁文件里面国瓮,它設(shè)置的較大會使棧開辟較大的值灭必,可能增加內(nèi)存的開銷和啟動時間狞谱。?
3.碎片問題:對于堆來講乃摹,頻繁的new/delete勢必會造成內(nèi)存空間的不連續(xù),從而造成大量的碎片跟衅,使程序效率降低孵睬。對于棧來講,則不會存在這個問題伶跷,因為棧是先進(jìn)后出的隊列掰读,他們是如此的一一對應(yīng),以至于永遠(yuǎn)都不可能有一個內(nèi)存塊從棧中間彈出.
4.生長方向:對于堆來講叭莫,生長方向是向上的蹈集,也就是向著內(nèi)存地址增加的方向;對于棧來講雇初,它的生長方向是向下的拢肆,是向著內(nèi)存地址減小的方向增長。?
5.分配方式:堆都是動態(tài)分配的,沒有靜態(tài)分配的堆郭怪。棧有2種分配方式:靜態(tài)分配和動態(tài)分配支示。靜態(tài)分配是編譯器完成的,比如局部變量的分配鄙才。動態(tài)分配由alloca函數(shù)進(jìn)行分配颂鸿,但是棧的動態(tài)分配和堆是不同的,他的動態(tài)分配是由編譯器進(jìn)行釋放攒庵,無需我們手工實現(xiàn)嘴纺。
7.分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計算機(jī)會在底層對棧提供支持:分配專門的寄存器存放棧的地址叙甸,壓棧出棧都有專門的指令執(zhí)行颖医,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫提供的裆蒸,它的機(jī)制是很復(fù)雜的熔萧。例如為了分配一塊內(nèi)存,庫函數(shù)會按照一定的算法(具體的算法可以參考數(shù)據(jù)結(jié)構(gòu)/操作系統(tǒng))在堆內(nèi)存中搜索可用的足夠大小的空間僚祷,如果沒有足夠大小的空間(可能是由于內(nèi)存碎片太多)佛致,就有可能調(diào)用系統(tǒng)功能去增加程序數(shù)據(jù)段的內(nèi)存空間,這樣就有機(jī)會分到足夠大小的內(nèi)存辙谜,然后進(jìn)行返回俺榆。顯然,堆的效率比棧要低得多装哆。