一般來說,寫程序就是與數(shù)據(jù)打交道,在執(zhí)行程序某一功能的時候,將該功能所需要的數(shù)據(jù)加載到內(nèi)存中,然后在執(zhí)行完畢的時候釋放掉該內(nèi)存。
數(shù)據(jù)在內(nèi)存中的存放方式有以下幾種:
(1)棧區(qū)——由編譯器自動分配并且釋放,該區(qū)域一般存放函數(shù)的參數(shù)值、局部變量的值等。
(2)堆區(qū)——由程序員分配釋放。
(3)寄存器區(qū)——用來保存棧頂指針和指令指針。
(4)全局區(qū)(靜態(tài)區(qū))——全局變量和靜態(tài)變量的存儲是放在一塊的。
(5)文字常量區(qū)——放常量字符串的區(qū)域。
(6)程序代碼區(qū)——存放函數(shù)體的二進(jìn)制代碼。
棧和堆的區(qū)別:
(1)內(nèi)存申請方式上的不同
<1>棧:由系統(tǒng)自動分配。
<2>堆:由程序員自己申請,需要指明變量的大小。
(2)系統(tǒng)響應(yīng)的不同
<1>棧:只要棧的剩余空間大于所申請空間,系統(tǒng)就為程序提供 內(nèi)存,否則提示棧溢出。
<2>堆:系統(tǒng)收到程序申請空間的要求后,會遍歷一個操作系統(tǒng),用于記錄內(nèi)存空閑地址的鏈表,當(dāng)找到一個空間大于所申請空間的堆結(jié)點(diǎn)后,就會就會將該結(jié)點(diǎn)從記錄內(nèi)存空閑地址的鏈表中刪除。并將該結(jié)點(diǎn)的內(nèi)存分配給程序,然后在這塊內(nèi)存區(qū)域的首地址處記錄分配的大小,這樣在使用delete來釋放內(nèi)存的時候,delete才能正確的識別并刪除該內(nèi)存區(qū)域的所有變量。另外,申請的內(nèi)存空間與堆結(jié)點(diǎn)上的內(nèi)存空間不一定相等,這時系統(tǒng)就會自動將堆結(jié)點(diǎn)上多出來的那一部分內(nèi)存空間回收到空閑鏈表中。
(3)空間大小的不同
<1>棧:在Windows下,棧是一塊連續(xù)的內(nèi)存的區(qū)域,其大小數(shù)值是編譯時就確定的常數(shù),是由系統(tǒng)預(yù)先根據(jù)棧頂?shù)牡刂泛蜅5淖畲笕萘慷x好的。如果你的數(shù)據(jù)申請的內(nèi)存空間超過棧的空間,那么系統(tǒng)會提示棧溢出。因此,別指望棧能存儲比較大的數(shù)據(jù)。
<2>堆:堆是不連續(xù)的內(nèi)存區(qū)域。各塊區(qū)域由鏈表將它們串聯(lián)起來。堆的上限是由系統(tǒng)中有效的虛擬內(nèi)存來定的。因此獲得的空間比較大,而且獲得空間的方式也比較靈活。
(4)執(zhí)行效率的不同
<1>棧:棧由系統(tǒng)自動分配,因此速度較快。
<2>堆:堆是由程序員分配的內(nèi)存,速度一般比較慢,而且容易產(chǎn)生內(nèi)存碎片。
(5)執(zhí)行函數(shù)時的不同
<1>棧:在函數(shù)調(diào)用時,第一個進(jìn)棧的是被調(diào)用函數(shù)下一行的內(nèi)存地址;其次是函數(shù)的參數(shù),假如參數(shù)多于一個,那么次序是從右往左;最后才是函數(shù)的局部變量。由于棧的先進(jìn)后出原則,因此它永遠(yuǎn)不可能產(chǎn)生內(nèi)存碎片。
<2>堆:堆是一大堆不連續(xù)的內(nèi)存區(qū)域,在系統(tǒng)中由鏈表串接起來。堆的運(yùn)行效率比棧要低得多,而且也容易產(chǎn)生碎片。優(yōu)點(diǎn)是堆可以存儲相當(dāng)多的數(shù)據(jù),并且一些細(xì)節(jié)可以由程序員安排。
-
二進(jìn)制
+關(guān)注
關(guān)注
2文章
807瀏覽量
42335 -
C++
+關(guān)注
關(guān)注
22文章
2119瀏覽量
75330 -
編譯器
+關(guān)注
關(guān)注
1文章
1662瀏覽量
50232
原文標(biāo)題:【博文連載】C++中的“棧與堆”
文章出處:【微信號:ChinaAET,微信公眾號:電子技術(shù)應(yīng)用ChinaAET】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
堆和棧的區(qū)別在哪
STM32堆棧區(qū)劃分
單片機(jī)堆和棧的區(qū)別在哪
明確區(qū)分堆與棧,堆和棧究竟有什么區(qū)別?

C語言編程中的“堆”和“棧”七大不同之處

C語言內(nèi)存堆與棧的筆記資料說明

評論