c 記憶體分配方式

2021-08-03 18:35:24 字數 1637 閱讀 6202

在c++中,記憶體分為5個區,它們分別是堆,棧,自由儲存區,全域性/靜態和常量儲存區

棧:在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些記憶體自動釋放。棧記憶體分配 運算內置於處理器的指令集中,效率很高,但是分配的記憶體容量有限。

注:編譯期限制棧大小和系統限制棧深度不同,編譯限制棧深度是限制單個函式棧幀的大小,而系統限制棧深是限制程序主線程的棧深,限制的是整個函式呼叫鏈的最大棧深,這個棧深是函式呼叫鏈上各個函式棧幀大小之和。

堆:就是由new分配的記憶體塊,他們釋放由程式設計師去控制,一般乙個new就要對應乙個delete。如果程式設計師沒有釋放,那麼在程式結束後,作業系統會自動**。

自由儲存區:就是那些由malloc等分配的記憶體塊,他和堆十分相似,不過它是用free來結束生命的。

全域性/靜態儲存區:全域性變數和靜態變數被分配到同一塊記憶體中(和c語言不同)

常量儲存區:這是一塊比較特殊的儲存區域,這裡方的是常量,不允許被修改

堆與棧的區別:

1.空間大小不同

2.能否產生碎片不同

3.生長方向不同

4.分配方式不同

5.分配效率不同

6.管理方式不同

空間大小:一般來講在32位系統下,堆記憶體可以達到4g的空間,從這個角度來講堆記憶體幾乎是沒有限制的。但對於棧來說一般是有限制的,windows上一般預設的棧大小為1024k,linux為10240k,棧的大小可以被修改。

碎片問題:對於堆來講,頻繁的new/delete會導致記憶體空間的不連續,從而造成大量的碎片,使程式效率降低。而,棧是先進後出的佇列,則不存在這個問題。

生長方向:對於堆來說,生長方向是向上的也是向著記憶體位址增長的方向;對於棧來說,他的生長方向是向下的,向著記憶體位址減小的方向增長

分配方式:堆是動態分配的,沒有靜態分配的堆。而棧有兩種分配方式:靜態分配和動態分配。靜態分配時由編譯器完成的,比如

分配效率:堆是c/c++函式庫提供的,他的機制很複雜,例如為了分配一塊記憶體,庫函式會按照一定的演算法(具體演算法可以參考資料結構/作業系統)在堆記憶體中搜尋可用的足夠大小的空間。如果沒有足夠大的空間(可能由於記憶體碎片太多),就可能呼叫系統功能去增加程式資料段的記憶體空間,這樣就有機會分得足夠大的記憶體,然後返回。而棧是機器系統提供的資料結構,計算機會在底層對棧提供支援:分配專門的暫存器存放棧的位址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。

管理方式:對於棧來講,是由編譯器自動管理,無需我們手工控制;對於堆來說,釋放工作由程式設計師控制,容易產生記憶體碎片

無論是堆還是棧都要防止越界的現象發生,以為越界的結果要麼是程式崩潰要麼是摧毀程式的堆結構和棧結構產生意想不到的結果。

C記憶體分配方式與C 記憶體分配方式

c記憶體分配方式 注 malloc函式的實質體現在,它有乙個將可用的記憶體塊連線為乙個長長的列表的所謂空閒鍊錶。呼叫malloc函式時,它沿連線表尋找乙個大到足以滿足使用者請求所需要的記憶體塊。然後,將該記憶體塊一分為二 一塊的大小與使用者請求的大小相等,另一塊的大小就是剩下的位元組 接下來,將分配...

C 記憶體分配方式

在c 中,記憶體分成5個區 堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區。棧 就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變數的儲存區。裡面的變數通常是區域性變數 函式引數等。在乙個程序中,位於使用者虛擬位址空間頂部的是使用者棧,編譯器用它來實現函式的呼叫。和堆一樣,使用者棧在程...

C 記憶體分配方式

乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數名,區域性變數的名等。其操作方式類似於資料結構中的棧。2 堆區 heap 由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中的堆是兩回事,分配方式倒是類似於...