本文引用地址:[http://www.eepw.com.cn/article/201901/396398.htm]
對于編程初學(xué)者來說會接觸到一些難以理解的名稱,比如堆(heap)暖呕、棧(stack)斜做、堆棧等。初學(xué)開發(fā)過程中往往讓人混淆不清湾揽。今天我們來談?wù)劧押蜅5木唧w區(qū)別瓤逼,來幫助初學(xué)者理清思路。
堆和棧的區(qū)別一直都是永恒的話題库物,為此我也查了很多的資料霸旗,以防自己的理解錯誤,而給他人造成理解偏差戚揭。
先從簡單的一個例子引出堆和棧:
void function(){
int *p = (int )malloc(10sizeof(int));
}
這是C語言開發(fā)學(xué)習(xí)過程中诱告,必不可免要學(xué)習(xí)的知識,動態(tài)分配一塊空間民晒,空間在堆區(qū)大小是40字節(jié)(32位系統(tǒng)中)精居。而定義的指針變量p是局部變量(在棧區(qū)中 占用4字節(jié)空間),用來存放剛剛前面動態(tài)分配的空間的首地址潜必⊙プ耍可以看出,在這一句代碼中同時包含了棧和堆磁滚,如圖1所示佛吓。
我們從以下幾個方面比較一下堆和棧:
(1)存儲內(nèi)容不同
棧:在函數(shù)調(diào)用時,棧中存放的是函數(shù)中(底下是函數(shù)調(diào)用后的下一條指令)各個參數(shù)(局部變量)垂攘。
堆:一般是在堆的頭部用一個字節(jié)存放堆的大小维雇。堆中的具體內(nèi)容有程序員安排。
(2)管理方式上不同
棧:由系統(tǒng)自動分配空間搜贤,同時系統(tǒng)自動釋放空間谆沃。 例如,聲明在函數(shù)中一個局部變量 int b; 系統(tǒng)自動在棧中為b開辟空間仪芒,當(dāng)對應(yīng)的生存周期結(jié)束后椦溆埃空間自動釋放耕陷。
堆:需要程序員手動申請并且手動釋放,并指明大小据沈,在C語言中malloc函數(shù)申請哟沫,釋放free函數(shù),在C++中 new和delete實現(xiàn)锌介。
(3)空間大小不同
棧:獲取空間較小嗜诀。在Windows下,一般大小是1M或2M孔祸,當(dāng)剩余椔「遥空間不足時,分配失敗overflow崔慧。
堆:獲得空間根據(jù)系統(tǒng)的有效虛擬內(nèi)存有關(guān)拂蝎,比較靈活,比較大惶室。
(4)能否產(chǎn)生碎片不同
棧:不會產(chǎn)生碎片温自,空間連續(xù)。
堆:采用的是鏈表的存儲方式皇钞,會產(chǎn)生碎片悼泌。
(5)生長方向不同
棧: 向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域夹界。
堆: 向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)馆里,是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來存儲的空閑內(nèi)存地址的掉盅,自然是不連續(xù)的也拜,而鏈表的遍歷方向是由低地址向高地址。
(6)分配方式不同
棧:有2種分配方式:靜態(tài)分配和動態(tài)分配趾痘,靜態(tài)由編譯器完成慢哈,例如局部變量;動態(tài)由alloca函數(shù)實現(xiàn),并且編譯器會進(jìn)行釋放永票。
堆: 都是動態(tài)分配的卵贱,沒有靜態(tài)分配的堆。
(7)分配效率不同
棧:由系統(tǒng)自動分配侣集,速度較快键俱。但程序員是無法控制的。
堆:由new分配的內(nèi)存世分,一般速度比較慢编振,而且容易產(chǎn)生內(nèi)存碎片,不過用起來方便臭埋。
以上是棧和堆幾個方面的不同踪央,希望通過上面的資料可以幫助初學(xué)者分清堆和棧臀玄。