C++中堆(heap)和棧(stack)的區別(面試中被問到的題目)
文章推薦指數: 80 %
簡單的可以理解為: heap:是由malloc之類函式分配的空間所在地。
地址是由低向高增長的。
stack:是自動分配變數,... get和post的區別--面試經常 ...
程式人生>>C++中堆(heap)和棧(stack)的區別(面試中被問到的題目)
C++中堆(heap)和棧(stack)的區別(面試中被問到的題目)
阿新••發佈:2019-01-01
說起會了解這個東西,還是比較尷尬的,在學校裡面老師一般不會講解C++的堆和棧,大多數人瞭解的堆和棧是資料結構裡面的概念,而這裡一般面試官想問的是C++的記憶體分割槽管理方式。
首先說明,在C++中,記憶體分為5個區:堆、佔、自由儲存區、全域性/靜態儲存區、常量儲存區
棧:是由編譯器在需要時自動分配,不需要時自動清除的變數儲存區。
通常存放區域性變數、函式引數等。
堆:是由new分配的記憶體塊,由程式設計師釋放(編譯器不管),一般一個new與一個delete對應,一個new[]與一個delete[]對應。
如果程式設計師沒有釋放掉, 資源將由作業系統在程式結束後自動回收。
自由儲存區:是由malloc等分配的記憶體塊,和堆十分相似,用free來釋放。
全域性/靜態儲存區:全域性變數和靜態變數被分配到同一塊記憶體中(在C語言中,全域性變數又分為初始化的和未初始化的,C++中沒有這一區分)。
常量儲存區:這是一塊特殊儲存區,裡邊存放常量,不允許修改。
(注意:堆和自由儲存區其實不過是同一塊區域(這句話是有問題的,下文解釋),new底層實現程式碼中呼叫了malloc,new可以看成是malloc智慧化的高階版本,詳情參見new和malloc的區別及實現方法, 以及這一篇)
疑問一:堆和自由儲存區是不是同一塊區域
自由儲存區是C++基於new操作符的一個抽象概念,凡是通過new操作符進行記憶體申請,該記憶體即為自由儲存區。
而堆是作業系統中的術語,是作業系統所維護的一塊特殊記憶體,用於程式的記憶體動態分配,C語言使用malloc從堆上分配記憶體,使用free釋放已分配的對應記憶體。
自由儲存區不等於堆,如上所述,佈局new就可以不位於堆中。
什麼叫佈局new,對應的常規new又是什麼?
疑問二:堆和棧的區別
堆
棧
管理方式
堆中資源由程式設計師控制(容易產生memory leak)
棧資源由編譯器自動管理,無需手工控制
記憶體管理機制
系統有一個記錄空閒記憶體地址的連結串列,當系統收到程式申請時,遍歷該連結串列,尋找第一個空間大於申請空間的堆結點,刪 除空閒結點連結串列中的該結點,並將該結點空間分配給程式(大多數系統會在這塊記憶體空間首地址記錄本次分配的大小,這樣delete才能正確釋放本記憶體 空間,另外系統會將多餘的部分重新放入空閒連結串列中)
只要棧的剩餘空間大於所申請空間,系統為程式提供記憶體,否則報異常提示棧出。
(這一塊理解一下連結串列和佇列的區別,不連續空間和連續空間的區別,應該就比較好理解這兩種機制的區別了)
空間大小
堆是不連續的記憶體區域(因為系統是用連結串列來儲存空閒記憶體地址,自然不是連續的),堆大小受限於計算機系統中有效的虛擬記憶體(32bit 系統理論上是4G),所以堆的空間比較靈活,比較大
棧是一塊連續的記憶體區域,大小是作業系統預定好的,windows下棧大小是2M(也有是1M,在 編譯時確定,VC中可設定)。
碎片問題
對於堆,頻繁的new/delete會造成大量碎片,使程式效率降低
對於棧,它是一個先進後出的佇列,進出一一對應,不會產生碎片。
(看到這裡我突然明白了為什麼面試官在問我堆和棧的區別之前先問了我棧和佇列的區別)
生長方向
堆向上,向高地址方向增長。
棧向下,向低地址方向增長。
分配方式
堆都是動態分配(沒有靜態分配的堆)
棧有靜態分配和動態分配,靜態分配由編譯器完成(如區域性變數分配),動態分配由alloca函式 分 配,但棧的動態分配的資源由編譯器進行釋放,無需程式設計師實現。
分配效率
堆由C/C++函式庫提供,機制很複雜。
所以堆的效率比棧低很多。
棧是極其系統提供的資料結構,計算機在底層對棧提供支援,分配專門 寄存 器存放棧地址,棧操作有專門指令。
程式示例
intb;
//main.cpp
inta=0;//全域性初始化區
char*p1;//全域性未初始化區
main(){intb;//棧
chars[]="abc";//棧
char*p2;//棧
char*p3="123456";//123456/0在常量區,p3在棧上。
staticintc=0;//全域性(靜態)初始化區
p1=(char*)malloc(10)
p2=(char*)malloc(20)//分配得來得10和20位元組的區域就在堆區。
strcpy(p1,"123456");//123456/0放在常量區,編譯器可能會將它與p3所指向的"123456"優化成一個地方。
}
據說有這麼一個段子?
使用棧就象我們去飯館裡吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。
使用堆就象是自己動手做喜歡吃的菜餚,比較麻煩,但是比較符合自己的口味,而且自由度大。
參考連結(除了文中直接引入超連結的部分):
如何用pandas讀取CVS格式資料
«上一篇
AndroidTCP/IP傳送接收16進位制資料下一篇»
相關推薦
C++中堆(heap)和棧(stack)的區別(面試中被問到的題目)
說起會了解這個東西,還是比較尷尬的,在學校裡面老師一般不會講解C++的堆和棧,大多數人瞭解的堆和棧是資料結構裡面的概念,而這裡...
java中堆(heap)和棧(stack)的區別
在學習java的過程中,經常會見到椎和棧的介紹,但是一直都是瞭解了個大概,而且看了之後又經常會忘掉,所以這次在網上查找了...
關於DSP中堆heap和棧stack的理解
之前一直不是很清楚堆和棧之間的區別,因為在windows下不是很注意區分它們。
今天查了些資料,關於C6000DSP堆和棧有如...
mybatis中的#和$的區別?面試經常問到!!
1.#將傳入的資料都當成一個字串,會對自動傳入的資料加一個雙引號。
如:orderby#user_id#,如果傳入的值是111,那麼解析成sql時的值為o...
記憶體中堆(heap)與棧(stack)的區別
根源出處已不可考證,不過寫的很好,轉來當作備忘。
一個程式一般分為3段:text段,data段,bss段。
TEXT段:...
堆(Heap)和棧(Stack)
數據結構itemext調用.com結束baidu決定text堆,隊列優先,先進先出(FIFO—first...
堆(heap)和棧(stack)、記憶體洩漏(memoryleak)和記憶體溢位
簡單的可以理解為:
heap:是由malloc之類函式分配的空間所在地。
地址是由低向高增長的。
stack:是自動分配變數,...
get和post的區別--面試經常被問到!(一)
修改史記限制url地址完整返回協議頭作用delet
了解歷史
get和post是HTTP與服務器交互的方...
Iterator和ListIterator的區別---面試題
iteratorset面試區別lis什麽的區別是什麽接口Iterator和ListIterator的區別是...
include和require的區別--面試題
PHPinclude和require語句
在PHP中,您可以在伺服器執行PHP檔案之前在該檔案...
搜尋
基礎教學
Mysql入門
Sql入門
Android入門
Docker入門
Go語言入門
Ruby程式入門
Python入門
Python進階
Django入門
Python爬蟲入門
最近訪問
C++中堆(heap)和棧(stack)的區別(面試中被問到的題目)
sharepoint+2016+學習系列篇(12)-自定義列表應用篇-(1)建立一個自定義列表(Create+a+custom+list)
python格式化字串含義
XOR+異或的性質及應用
w8_struct
設定雙核瀏覽器的瀏覽模式
ant+eclipse知識點詳解及使用案例
Android24.2.0支援庫中的SnapHelper學習和使用
PHP中curl模擬post上傳及接收檔案
easyui+tabs元件關閉tab時釋放iframe佔用記憶體
延伸文章資訊
- 1Java筆記:觀念釐清-stack及heap的差異 - iT 邦幫忙
Java筆記:觀念釐清-stack及heap的差異 · 基本型別: byte 、 short 、 int 、 long 、 float 、 double 、 boolean 、 char · 類...
- 2記憶體- stack 與heap - iT 邦幫忙::一起幫忙解決難題
- 3Stack 與Heap 有何差別. 程式設計相關的行業 - Medium
簡單說, Stack 是拿來給程式呼叫function 時存放function 資料用的,而Heap 是用來存放並且管理,程式全部所需要用到的變數與資料。 參考資訊. https:// ...
- 4stack vs heap:執行時期儲存兩大要角 - 劉逸的留意世界
但許多工程師卻搞不清楚記憶體中的stack跟heap space到底有何居別,下面 ... 尤其在java中有時候會出現stack overflow或heap overflow到底兩者差異在 ...
- 5Java 面試- JVM 的Stack 和Heap - Laugh Now