對(duì)于編程初學(xué)者來說會(huì)接觸到一些難以理解的名稱锨侯,比如堆(heap)嫩海、棧(stack)、堆棧(stack)等囚痴。初學(xué)開發(fā)過程中往往讓人混淆不清叁怪。今天我們來談?wù)劧押蜅5木唧w區(qū)別,來幫助初學(xué)者理清思路深滚。
堆和棧的區(qū)別一直都是永恒的話題奕谭,為此筆者也查了很多的資料,以防自己的理解錯(cuò)誤痴荐,而給他人造成理解偏差展箱。
“堆”和“棧”
先從簡單的一個(gè)例子引出堆和棧:
void function()
{
int *p = (int *)malloc(10*sizeof(int));
}
這是C語言開發(fā)學(xué)習(xí)過程中蹬昌,必不可免要學(xué)習(xí)的知識(shí),動(dòng)態(tài)分配一塊空間攀隔,空間在堆區(qū)大小是40字節(jié)(32位系統(tǒng)中)皂贩。而定義的指針變量p是局部變量,在棧區(qū)中 占用4字節(jié)空間昆汹,用來存放剛剛前面動(dòng)態(tài)分配的空間的首地址明刷。
可以看出,在這一句代碼中同時(shí)包含了棧和堆满粗,如下圖所示辈末。
堆和棧
堆和棧的區(qū)別
我們從以下幾個(gè)方面比較一下堆和棧:
1、存儲(chǔ)內(nèi)容不同
棧:在函數(shù)調(diào)用時(shí),棧中存放的是函數(shù)中各個(gè)參數(shù)(局部變量)挤聘。棧底下是函數(shù)調(diào)用后的下一條指令轰枝。
堆:一般是在堆的頭部用一個(gè)字節(jié)存放堆的大小。堆中的具體內(nèi)容有程序員安排组去。
2鞍陨、管理方式上不同
棧:由系統(tǒng)自動(dòng)分配空間,同時(shí)系統(tǒng)自動(dòng)釋放空間从隆。例如诚撵,聲明在函數(shù)中一個(gè)局部變量“int b“。系統(tǒng)自動(dòng)在棧中為b開辟空間键闺,當(dāng)對(duì)應(yīng)的生存周期結(jié)束后検傺蹋空間自動(dòng)釋放。
堆:需要程序員手動(dòng)申請(qǐng)并且手動(dòng)釋放辛燥,并指明大小筛武。在C語言中malloc函數(shù)申請(qǐng),釋放free函數(shù)购桑,在C++中new和delete實(shí)現(xiàn)畅铭。
3、空間大小不同
棧:獲取空間較小勃蜘。在Windows下硕噩,一般大小是1M或2M,當(dāng)剩余楃怨保空間不足時(shí)炉擅,分配失敗overflow。
堆:獲得空間根據(jù)系統(tǒng)的有效虛擬內(nèi)存有關(guān)阳惹,比較靈活谍失,比較大。
4莹汤、能否產(chǎn)生碎片不同
棧:不會(huì)產(chǎn)生碎片快鱼,空間連續(xù)。
堆:采用的是鏈表的存儲(chǔ)方式纲岭,會(huì)產(chǎn)生碎片抹竹。
小編給大家推薦一個(gè)學(xué)習(xí)氛圍超好的地方,C/C++交流企鵝裙:【8.7.0+九.六.三+2.5.1】適合在校大學(xué)生止潮,小白窃判,想轉(zhuǎn)行,想通過這個(gè)找工作的加入喇闸。裙里有大量學(xué)習(xí)資料袄琳,有大神解答交流問題询件,每晚都有免費(fèi)的直播課程
5、生長方向不同
棧:向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)唆樊,是一塊連續(xù)的內(nèi)存的區(qū)域宛琅。
堆:向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域窗轩。這是由于系統(tǒng)是用鏈表來存儲(chǔ)的空閑內(nèi)存地址的夯秃,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址痢艺。
6仓洼、分配方式不同
棧:有2種分配方式——靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)由編譯器完成堤舒,例如局部變量;動(dòng)態(tài)由alloca函數(shù)實(shí)現(xiàn)色建,并且編譯器會(huì)進(jìn)行釋放。
堆:都是動(dòng)態(tài)分配的舌缤,沒有靜態(tài)分配的堆箕戳。
7、分配效率不同
棧:由系統(tǒng)自動(dòng)分配国撵,速度較快陵吸。但程序員是無法控制的。
堆:由new分配的內(nèi)存介牙,一般速度比較慢壮虫,而且容易產(chǎn)生內(nèi)存碎片,不過用起來方便环础。
以上是棧和堆幾個(gè)方面的不同囚似,希望通過上面的資料可以幫助初學(xué)者分清堆和棧。