C 堆和棧區別

2021-10-06 17:32:47 字數 1876 閱讀 7346

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

棧:是由編譯器在需要時自動分配,不需要時自動清除的變數儲存區。通常存放區域性變數、函式引數等。

堆:是由new分配的記憶體塊,由程式設計師釋放(編譯器不管),一般乙個new與乙個delete對應,乙個new與乙個delete對應。如果程式設計師沒有釋放掉,資源將由作業系統在程式結束後自動**

自由儲存區:是由malloc等分配的記憶體塊,和堆十分相似,用free來釋放。

全域性/靜態儲存區:全域性變數和靜態變數被分配到同一塊記憶體中(在c語言中,全域性變數又分為初始化的和未初始化的,c++中沒有這一區分)。

常量儲存區:這是一塊特殊儲存區,裡邊存放常量,不允許修改。

(注意:堆和自由儲存區其實不過是同一塊區域,new底層實現**中呼叫了malloc,new可以看成是malloc智慧型化的高階版本)

一. 堆與棧的討論:

管理方式:堆中資源由程式設計師控制(容易產生memory leak), 棧資源由編譯器自動管理,無需手工控制。

系統響應:對於堆,應知道系統有乙個記錄空閒記憶體位址的鍊錶,當系統收到程式申請時,遍歷該鍊錶,尋找第乙個空間大於申請空間的堆結點,刪    除空閒結點鍊錶中的該結點,並將該結點空間分配給程式(大多數系統會在這塊記憶體空間首位址記錄本次分配的大小,這樣delete才能正確釋放本記憶體  空間,另外系統會將多餘的部分重新放入空閒鍊錶中)。對於棧,只要棧的剩餘空間大於所申請空間,系統為程式提供記憶體,否則報異常提示棧出。

空間大小:堆是不連續的記憶體區域(因為系統是用鍊錶來儲存空閒記憶體位址,自然不是連續的),堆大小受限於計算機系統中有效的虛擬記憶體(32bit  系統理論上是4g),所以堆的空間比較靈活,比較大。棧是一塊連續的記憶體區域,大小是作業系統預定好的,windows下棧大小是2m(也有是1m,在  編譯時確定,vc中可設定)。

碎片問題:對於堆,頻繁的new/delete會造成大量碎片,使程式效率降低。 對於棧,它是乙個先進後出的佇列,進出一一對應,不會產生碎片。

生長方向:堆向上,向高位址方向增長。棧向下,向低位址方向增長。

分配方式:堆都是動態分配(沒有靜態分配的堆)。棧有靜態分配和動態分配,靜態分配由編譯器完成(如區域性變數分配),動態分配由alloca函式  分    配,但棧的動態分配的資源由編譯器進行釋放,無需程式設計師實現。

分配效率:堆由c/c++函式庫提供,機制很複雜。所以堆的效率比棧低很多。棧是極其系統提供的資料結構,計算機在底層對棧提供支援,分配專門  寄存  器存放棧位址,棧操作有專門指令。

在windows下,棧位址是向低位址擴充套件的資料結構,是一塊連續的記憶體區域棧頂的位址和棧的最大容量是系統預先規定好的,在windows下,棧的大小是2mb而申請堆空間的大小一般小於2gb

棧的速度快,但是空間小,不靈活。

堆是向高位址擴充套件的資料結構,是不連續的記憶體區域。

這是由於系統是用鍊錶來儲存空閒記憶體位址的,自然是不連續的,而鍊錶的遍歷方向是由低位址向高位址的,而堆的大小受限於計算機系統中有效的虛擬記憶體,所以堆獲得的空間比較靈活,也比較大,但是速度相對慢些。

一般情況下,可以通過以下兩種方法更改棧的大小:

1.link時用 /stack  指定它的大小,或者在 .def 中使用stacksize指定它的大小。

2.使用控制台命令 「editbin」更改exe的棧空間大小,

需要注意的是,liunux預設棧空間大小為 8mb

c 棧和堆的區別

在c 中,記憶體分成5個區,他們分別是堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區。棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變數的儲存區。裡面的變數通常是區域性變數 函式引數等。堆,就是那些由new分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般乙個n...

C 堆和棧的區別

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

C堆和棧的區別

堆和棧的區別 一 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os ...