C 中的堆和棧

2021-08-28 08:21:07 字數 1546 閱讀 4842

在c++中,記憶體分為5個區:堆、棧、自由儲存區、靜態儲存區(或全域性儲存區)和常量儲存區。

堆和棧都是c++的記憶體儲存區之一,下面介紹堆和棧對比用法:

是機器系統提供的資料結構,是filo(first in last out)結構,計算機底層對它進行了支援,棧的記憶體分配內置於處理器的指令集(分配了專門的暫存器存放棧的位址,壓棧和出棧都有專門的指令),這也就決定了棧的分配效率較高。

是由c/c++函式庫提供的,由一套複雜的演算法實現。堆中有乙個記錄空閒記憶體位址的鍊錶,當系統收到程序的空間申請時,根據使用的分配演算法找到合適的位址空間。(比如first-fit演算法:遍歷此鍊錶,找到第乙個空間大於申請大小的空閒記憶體分配給程序,從空閒鍊錶中將此節點刪除,並記錄此次分配的大小,新增到已分配記憶體鍊錶中,另外將多餘的空閒空間新增到空閒鍊錶中,將分配記憶體的首位址返回給程序使用)此後程序可以合理地使用這塊空間,有時由於申請的空間太大,空閒鍊錶中找不到合適的記憶體,系統會使用mmap擴充套件有效堆記憶體,以獲得更多的虛擬位址空間。基於以上,堆的申請效率較低。

的空間較小,windows下棧的大小是乙個在編譯時就確定的常量,通常是1m或2m,在unbutu下一般是8m,centos下是10m,可以通過ulimit -a檢視,ulimit -s進行修改。

棧是一塊連續的空間,每次申請也是申請連續的大小。

的空間較大,一般和系統有關,32位系統堆大小一般為4g。

堆是由空閒記憶體位址鍊錶管理,堆空間是不連續的申請,每次申請都是在空閒空間鍊錶上找合適大小的空閒空間進行分配。

由於棧是系統進行分配和釋放,而且由於棧這種資料結構的特點filo,不會出現間隔的分配,所以棧不會有產生記憶體碎片,而堆是由程式設計師手動進行分配和釋放,存在碎片。

棧是由系統分配和釋放,當申請的空間小於剩餘的空間則進行分配,否則丟擲stack overflow。

棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如區域性變數的分配。動態分配由alloca函式進行分配(alloca不具可移植性, 而且在沒有傳統堆疊的機器上很難實現),用完由編譯器自動釋放,如果手動釋放會出錯。

alloca的函式具體用法:

標頭檔案: malloc.h

函式原型:void * __cdecl alloca(size_t);

#include #include int main()

堆是由程式設計師自己進行申請和釋放,使用new和malloc等申請,對應的由delete和free進行釋放。使用靈活,但容易發生記憶體洩露(memory leak)申請的空間可以很大。在專案很大時,難免發生記憶體洩露。較好的選擇是過載new和delete,跟蹤定位程式發生記憶體洩露的地方。

棧的生長方向是向下生長,即由記憶體高位址向低位址生長。

堆的生長方向是向上生長,由記憶體的低位址向高位址生長。

堆和棧之間由一層臨界區,大小可以進行修改,如果棧的空間到達臨界區,則會提示stack overflow。

c 中的堆和棧

1 記憶體分配方面 堆 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中的堆是兩回事,分配方式是類似於鍊錶。可能用到的關鍵字如下 new malloc delete free等等。棧 由編譯器 compiler 自動分配釋放,存放函式的引數值,區域性變數的值等。...

c 中的堆和棧

1 記憶體分配方面 堆 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中的堆是兩回事,分配方式是類似於鍊錶。可能用到的關鍵字如下 new malloc delete free等等。棧 由編譯器 compiler 自動分配釋放,存放函式的引數值,區域性變數的值等。...

C 中的堆和棧

原文c 中的堆和棧 棧上儲存的有 值型別,引用型別本身。棧記憶體就像一系列堆得越來越高的箱子。呼叫方法是,它的每乙個引數都被放入乙個箱子,並將這個箱子放到棧的最頂部。每個區域性變數也同樣分配到乙個箱子,並同樣放到棧的最頂部。方法結束後,它的所有箱子都從棧中移除。堆上儲存的有 引用型別的 物件 可空型...