C語(yǔ)言編程中的“堆”和“?!逼叽蟛煌?/h1>
對于編程初學(xué)者來(lái)說(shuō)會(huì )接觸到一些難以理解的名稱(chēng),比如堆(heap)、棧(stack)、堆棧(stack)等。初學(xué)開(kāi)發(fā)過(guò)程中往往讓人混淆不清。今天我們來(lái)談?wù)劧押蜅5木唧w區別,來(lái)幫助初學(xué)者理清思路。
本文引用地址:http://dyxdggzs.com/article/201901/396398.htm 堆和棧的區別一直都是永恒的話(huà)題,為此我也查了很多的資料,以防自己的理解錯誤,而給他人造成理解偏差。
先從簡(jiǎn)單的一個(gè)例子引出堆和棧:
void function(){
int *p = (int *)malloc(10*sizeof(int));
}
這是C語(yǔ)言開(kāi)發(fā)學(xué)習過(guò)程中,必不可免要學(xué)習的知識,動(dòng)態(tài)分配一塊空間,空間在堆區大小是40字節(32位系統中)。而定義的指針變量p是局部變量(在棧區中
占用4字節空間),用來(lái)存放剛剛前面動(dòng)態(tài)分配的空間的首地址??梢钥闯?,在這一句代碼中同時(shí)包含了棧和堆,如圖1所示。

圖1堆和棧
我們從以下幾個(gè)方面比較一下堆和棧:
(1)存儲內容不同
棧:在函數調用時(shí),棧中存放的是函數中(底下是函數調用后的下一條指令)各個(gè)參數(局部變量)。
堆:一般是在堆的頭部用一個(gè)字節存放堆的大小。堆中的具體內容有程序員安排。
(2)管理方式上不同
棧:由系統自動(dòng)分配空間,同時(shí)系統自動(dòng)釋放空間。 例如,聲明在函數中一個(gè)局部變量 int b;
系統自動(dòng)在棧中為b開(kāi)辟空間,當對應的生存周期結束后??臻g自動(dòng)釋放。
堆:需要程序員手動(dòng)申請并且手動(dòng)釋放,并指明大小,在C語(yǔ)言中malloc函數申請,釋放free函數,在C++中 new和delete實(shí)現。
(3)空間大小不同
棧:獲取空間較小。在Windows下,一般大小是1M或2M,當剩余??臻g不足時(shí),分配失敗overflow。
堆:獲得空間根據系統的有效虛擬內存有關(guān),比較靈活,比較大。
(4)能否產(chǎn)生碎片不同
棧:不會(huì )產(chǎn)生碎片,空間連續。
堆:采用的是鏈表的存儲方式,會(huì )產(chǎn)生碎片。
(5)生長(cháng)方向不同
棧: 向低地址擴展的數據結構,是一塊連續的內存的區域。
堆:
向高地址擴展的數據結構,是不連續的內存區域。這是由于系統是用鏈表來(lái)存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。
(6)分配方式不同
棧:有2種分配方式:靜態(tài)分配和動(dòng)態(tài)分配,靜態(tài)由編譯器完成,例如局部變量;動(dòng)態(tài)由alloca函數實(shí)現,并且編譯器會(huì )進(jìn)行釋放。
堆: 都是動(dòng)態(tài)分配的,沒(méi)有靜態(tài)分配的堆。
(7)分配效率不同
棧:由系統自動(dòng)分配,速度較快。但程序員是無(wú)法控制的。
堆:由new分配的內存,一般速度比較慢,而且容易產(chǎn)生內存碎片,不過(guò)用起來(lái)方便。
以上是棧和堆幾個(gè)方面的不同,希望通過(guò)上面的資料可以幫助初學(xué)者分清堆和棧。
對于編程初學(xué)者來(lái)說(shuō)會(huì )接觸到一些難以理解的名稱(chēng),比如堆(heap)、棧(stack)、堆棧(stack)等。初學(xué)開(kāi)發(fā)過(guò)程中往往讓人混淆不清。今天我們來(lái)談?wù)劧押蜅5木唧w區別,來(lái)幫助初學(xué)者理清思路。
本文引用地址:http://dyxdggzs.com/article/201901/396398.htm堆和棧的區別一直都是永恒的話(huà)題,為此我也查了很多的資料,以防自己的理解錯誤,而給他人造成理解偏差。
先從簡(jiǎn)單的一個(gè)例子引出堆和棧:
void function(){
int *p = (int *)malloc(10*sizeof(int));
}
這是C語(yǔ)言開(kāi)發(fā)學(xué)習過(guò)程中,必不可免要學(xué)習的知識,動(dòng)態(tài)分配一塊空間,空間在堆區大小是40字節(32位系統中)。而定義的指針變量p是局部變量(在棧區中 占用4字節空間),用來(lái)存放剛剛前面動(dòng)態(tài)分配的空間的首地址??梢钥闯?,在這一句代碼中同時(shí)包含了棧和堆,如圖1所示。

圖1堆和棧
我們從以下幾個(gè)方面比較一下堆和棧:
(1)存儲內容不同
棧:在函數調用時(shí),棧中存放的是函數中(底下是函數調用后的下一條指令)各個(gè)參數(局部變量)。
堆:一般是在堆的頭部用一個(gè)字節存放堆的大小。堆中的具體內容有程序員安排。
(2)管理方式上不同
棧:由系統自動(dòng)分配空間,同時(shí)系統自動(dòng)釋放空間。 例如,聲明在函數中一個(gè)局部變量 int b; 系統自動(dòng)在棧中為b開(kāi)辟空間,當對應的生存周期結束后??臻g自動(dòng)釋放。
堆:需要程序員手動(dòng)申請并且手動(dòng)釋放,并指明大小,在C語(yǔ)言中malloc函數申請,釋放free函數,在C++中 new和delete實(shí)現。
(3)空間大小不同
棧:獲取空間較小。在Windows下,一般大小是1M或2M,當剩余??臻g不足時(shí),分配失敗overflow。
堆:獲得空間根據系統的有效虛擬內存有關(guān),比較靈活,比較大。
(4)能否產(chǎn)生碎片不同
棧:不會(huì )產(chǎn)生碎片,空間連續。
堆:采用的是鏈表的存儲方式,會(huì )產(chǎn)生碎片。
(5)生長(cháng)方向不同
棧: 向低地址擴展的數據結構,是一塊連續的內存的區域。
堆: 向高地址擴展的數據結構,是不連續的內存區域。這是由于系統是用鏈表來(lái)存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。
(6)分配方式不同
棧:有2種分配方式:靜態(tài)分配和動(dòng)態(tài)分配,靜態(tài)由編譯器完成,例如局部變量;動(dòng)態(tài)由alloca函數實(shí)現,并且編譯器會(huì )進(jìn)行釋放。
堆: 都是動(dòng)態(tài)分配的,沒(méi)有靜態(tài)分配的堆。
(7)分配效率不同
棧:由系統自動(dòng)分配,速度較快。但程序員是無(wú)法控制的。
堆:由new分配的內存,一般速度比較慢,而且容易產(chǎn)生內存碎片,不過(guò)用起來(lái)方便。
以上是棧和堆幾個(gè)方面的不同,希望通過(guò)上面的資料可以幫助初學(xué)者分清堆和棧。
評論