日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言中栈堆,C语言中堆和栈的区别

發(fā)布時(shí)間:2023/12/1 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言中栈堆,C语言中堆和栈的区别 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

二.堆和棧的區(qū)別

1.申請方式

(1)棧(satck):由系統(tǒng)自動(dòng)分配。例如,聲明在函數(shù)中一個(gè)局部變量int b;系統(tǒng)自動(dòng)在棧中為b開辟空間。

(2)堆(heap):需程序員自己申請(調(diào)用malloc,realloc,calloc),并指明大小,并由程序員進(jìn)行釋放。容易產(chǎn)生memory leak.

eg:char? p;

p = (char *)malloc(sizeof(char));

但是,p本身是在棧中。

2.申請大小的限制

(1)棧:在windows下棧是向底地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存區(qū)域(它的生長方向與內(nèi)存的生長方向相反)。棧的大小是固定的。如果申請的空間超過棧的剩余空間時(shí),將提示overflow。

(2)堆:堆是高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)(它的生長方向與內(nèi)存的生長方向相同),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)使用鏈表來存儲(chǔ)空閑內(nèi)存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由底地址向高地址。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。

3.系統(tǒng)響應(yīng):

(1)棧:只要棧的空間大于所申請空間,系統(tǒng)將為程序提供內(nèi)存,否則將報(bào)異常提示棧溢出。

(2)堆:首先應(yīng)該知道操作系統(tǒng)有一個(gè)記錄空閑內(nèi)存地址的鏈表,但系統(tǒng)收到程序的申

請時(shí),會(huì)遍歷該鏈表,尋找第一個(gè)空間大于所申請空間的堆結(jié)點(diǎn),然后將該結(jié)點(diǎn)從空閑鏈表中刪除,并將該結(jié)點(diǎn)的空間分配給程序,另外,對于大多數(shù)系統(tǒng),會(huì)在這

塊內(nèi)存空間中的首地址處記錄本次分配的大小,這樣,代碼中的free語句才能正確的釋放本內(nèi)存空間。另外,找到的堆結(jié)點(diǎn)的大小不一定正好等于申請的大小,

系統(tǒng)會(huì)自動(dòng)的將多余的那部分重新放入空閑鏈表中。

說明:對于堆來講,對于堆來講,頻繁的new/delete勢必會(huì)造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對于棧來講,則不會(huì)存在這個(gè)問題,

4.申請效率

(1)棧由系統(tǒng)自動(dòng)分配,速度快。但程序員是無法控制的

(2)堆是由malloc分配的內(nèi)存,一般速度比較慢,而且容易產(chǎn)生碎片,不過用起來最方便。

5.堆和棧中的存儲(chǔ)內(nèi)容

(1)棧:在函數(shù)調(diào)用時(shí),第一個(gè)進(jìn)棧的主函數(shù)中后的下一條語句的地址,然后是函數(shù)的各個(gè)參數(shù),參數(shù)是從右往左入棧的,然后是函數(shù)中的局部變量。注:靜態(tài)變量是不入棧的。

當(dāng)本次函數(shù)調(diào)用結(jié)束后,局部變量先出棧,然后是參數(shù),最后棧頂指針指向最開始存的地址,也就是主函數(shù)中的下一條指令,程序由該點(diǎn)繼續(xù)執(zhí)行。

(2)堆:一般是在堆的頭部用一個(gè)字節(jié)存放堆的大小。

6.存取效率

(1)堆:char *s1=”hellow?tigerjibo”;是在編譯是就確定的

(2)棧:char s1[]=”hellow?tigerjibo”;是在運(yùn)行時(shí)賦值的;用數(shù)組比用指針?biāo)俣雀煲恍?#xff0c;指針在底層匯編中需要用edx寄存器中轉(zhuǎn)一下,而數(shù)組在棧上讀取。

補(bǔ)充:

棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計(jì)算機(jī)會(huì)在底層對棧提供支持:分配專門的寄存器存放棧

的地址,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫提供的,它的機(jī)制是很復(fù)雜的,例如為了分配一塊內(nèi)存,庫函數(shù)會(huì)按

照一定的算法(具體的算法可以參考數(shù)據(jù)結(jié)構(gòu)/操作系統(tǒng))在堆內(nèi)存中搜索可用的足夠大小的空間,如果沒有足夠大小的空間(可能是由于內(nèi)存碎片太多),就有可

能調(diào)用系統(tǒng)功能去增加程序數(shù)據(jù)段的內(nèi)存空間,這樣就有機(jī)會(huì)分到足夠大小的內(nèi)存,然后進(jìn)行返回。顯然,堆的效率比棧要低得多。

7.分配方式:

(1)堆都是動(dòng)態(tài)分配的,沒有靜態(tài)分配的堆。

(2)棧有兩種分配方式:靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動(dòng)態(tài)分配由alloca函數(shù)進(jìn)行分配,但是棧的動(dòng)態(tài)分配和堆是不同的。它的動(dòng)態(tài)分配是由編譯器進(jìn)行釋放,無需手工實(shí)現(xiàn)。

總結(jié)

以上是生活随笔為你收集整理的c语言中栈堆,C语言中堆和栈的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。