C 中的記憶體分配

2021-07-11 07:58:44 字數 2122 閱讀 8706

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

堆就是那些由 new 分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般乙個 new 就

要對應乙個 delete。如果程式設計師沒有釋放掉,那麼在程式結束後,作業系統會自動**。堆可以動態地擴充套件和收

縮。棧:

棧就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變數的儲存區。裡面的變數通常是區域性變數

、函式引數等。在乙個程序中,位於使用者虛擬位址空間頂部的是使用者棧,編譯器用它來實現函式的呼叫。和堆一樣

,使用者棧在程式執行期間可以動態地擴充套件和收縮。

自由儲存區:

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

命的。全域性/靜態儲存區:

全域性/靜態儲存區,全域性變數和靜態變數被分配到同一塊記憶體中,在以前的 c 語言中,全域性變數又分為初始化

的和未初始化的(初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數與靜態變數在相鄰的另一塊區域

,同時未被初始化的物件儲存區可以通過 void* 來訪問和操縱,程式結束後由系統自行釋放),在 c++ 裡面沒有

這個區分了,他們共同占用同一塊記憶體區。

常量儲存區:

常量儲存區,這是一塊比較特殊的儲存區,他們裡面存放的是常量,不允許修改(當然,你要通過非正當手段

也可以修改,而且方法很多)

堆和棧的區別分為一下幾個地方:

1、管理方式不同;

2、空間大小不同;

3、能否產生碎片不同;

4、生長方向不同;

5、分配方式不同;

6、分配效率不同

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

生memory leak。

空間大小:一般來講在 32 位系統下,堆記憶體可以達到4g的空間,從這個角度來看堆記憶體幾乎是沒有什麼限制

的。但是對於棧來講,一般都是有一定的空間大小的,例如,在vc6下面,預設的棧空間大小是1m(好像是,記不

清楚了)。當然,我們可以修改:開啟工程,依次操作選單如下:project->setting->link,在 category 中選中 

output,然後在 reserve 中設定堆疊的最大值和 commit。注意:reserve 最小值為 4byte;commit 是保留在虛

擬記憶體的頁檔案裡面,它設定的較大會使棧開闢較大的值,可能增加記憶體的開銷和啟動時間。

碎片問題:對於堆來講,頻繁的 new/delete 勢必會造成記憶體空間的不連續,從而造成大量的碎片,使程式效

率降低。對於棧來講,則不會存在這個問題,因為棧是先進後出的佇列,他們是如此的一一對應,以至於永遠都不

可能有乙個記憶體塊從棧中間彈出,在他彈出之前,在他上面的後進的棧內容已經被彈出,詳細的可以參考資料結構

,這裡我們就不再一一討論了。

生長方向:對於堆來講,生長方向是向上的,也就是向著記憶體位址增加的方向;對於棧來講,它的生長方向是

向下的,是向著記憶體位址減小的方向增長。

分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編

譯器完成的,比如區域性變數的分配。動態分配由 malloc 函式進行分配,但是棧的動態分配和堆是不同的,他的動

態分配是由編譯器進行釋放,無需我們手工實現。

分配效率:棧是機器系統提供的資料結構,計算機會在底層對棧提供支援:分配專門的暫存器存放棧的位址,

壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是 c/c++ 函式庫提供的,它的機制是很複雜的

,例如為了分配一塊記憶體,庫函式會按照一定的演算法(具體的演算法可以參考資料結構/作業系統)在堆記憶體中搜尋

可用的足夠大小的空間,如果沒有足夠大小的空間(可能是由於記憶體碎片太多),就有可能呼叫系統功能去增加程

序資料段的記憶體空間,這樣就有機會分到足夠大小的記憶體,然後進行返回。顯然,堆的效率比棧要低得多。

一般所說的堆疊(stack)往往是指棧,先進後出,它是一塊記憶體區。用以存放程式的區域性變數,臨時變數,函式的引數,返回位址等。在這塊區域中的變數的分配和釋放由系統自動進行。不需要使用者的參與。   

而在堆(heap,先進先出)上的空間則是由使用者進行分配,並由使用者負責釋放

c 中的記憶體分配

我們一般用new和delete在堆上動態的分配和釋放記憶體。但是我們實際去想過new是如何分配記憶體的?至少我沒有想 今天看了一下關於記憶體分配的知識的。得出了如下結論 new的工作原理是這樣的,先分配記憶體,在初始化物件 內建型別用值初始化,類物件用預設建構函式初始化,這裡引申一下,若乙個類沒有預...

C和C 中的記憶體分配

最近在課堂上聽到老師講了c語言中的記憶體分配,感覺挺深刻的,於是就寫下來,當做是對自己的提醒!微機原理的知識告訴我們,記憶體大致可以分為三部分 區 堆疊區 資料段 我的計算機學的不好,按照自己的理解 c和c 中有全域性變數,靜態變數以及區域性變數等幾類。全域性變數和靜態變數是在編譯的時候就已經分配好...

C 中記憶體分配詳解

程式執行時,特別要注意的是記憶體的分配。下面介紹c 程式設計中的記憶體分配。一 記憶體基本構成 可程式設計內存在基本上分為這樣的幾大部分 靜態儲存區 堆區和棧區。他們的功能不同,對他們使用方式也就不同。靜態儲存區 內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在。它主要存放靜態資...