C 探幽 記憶體分配

2021-10-10 15:39:28 字數 1624 閱讀 2218

棧,一般用於存放區域性變數或物件。

優勢在於:能夠在適當的時候自動生成、在適當的時候自動銷毀。棧物件的建立(只需要移動棧頂指標)速度比堆物件的建立速度塊(需要執行某種空間搜尋演算法)。

缺點:棧空間容量一般較小(1m-2m),體積比較大的物件不適合在棧中分配。而且遞迴函式最好不適用棧物件,因為隨著遞迴呼叫深度的增加,所需的棧空間也會線性增加,從而導致棧溢位。

int add(int a,int b)

int mian()

下邊這個例子中:

在函式add中,會生成兩個區域性變數a_,b_,返回的時候會生成另外乙個區域性變數c_。

在c=add(a,b)中,執行了c=c_的語句,c_是乙個臨時變數,在賦值完成後一段時間內被釋放。

所以編譯器在我們不知不覺的情況生成了好多臨時變數和物件,所以一般的如果函式需要傳遞大的引數,就需要使用const 引用的方式實現,以節約系統的資源。

堆——自由儲存區,在程式執行過程中動態分配,所以最大的特性就是動態性。所有堆物件的建立和銷毀都由程式設計師負責(new/delete)。

容易出現的記憶體錯誤:

記憶體洩漏:分配了堆物件,但是忘記釋放;

懸掛指標:釋放了物件,沒有將指標置null;

適用new分配堆物件的時候,會呼叫operator new操作,operator new會執行某種空間搜尋演算法,該搜尋過程會比較耗費時間。所以建立堆物件比棧物件慢。

所有的靜態物件、全域性物件都於靜態儲存區分配

關於全域性物件,是在main函式執行前就分配好了的,在main函式執行前,編譯器會生成_main函式進行所有全域性物件的構造和初始化操作。在main函式結束之前,會呼叫由編譯器產生的exit函式,來釋放所有的全域性物件。

void main(void)

對於區域性靜態物件,是在函式中定義的,類似於棧物件,但是多了乙個關鍵字static。它的生命週期是從其所在的函式第一次被呼叫執行到該靜態物件的宣告**時,直到整個程式結束時,才銷毀該物件。

而作為類的靜態成員,類的靜態成員物件伴隨著第乙個類的物件的產生而產生,在整個程式結束時消亡。如果建立了多個類物件,則這些類物件共享該靜態成員(該靜態成員屬於類,而不屬於某乙個物件)

如果乙個含有靜態成員的類作為基類被繼承了,其基類、子類也是共享該靜態成員的。所以當需要在這些class之間或這些class objects之間進行資料共享或通訊時,這樣的靜態成員無疑是很好的選擇。

棧物件自動釋放時,會呼叫自己的析構函式。如果在棧物件中封裝資源,而且在棧物件的析構函式中執行釋放資源的動作,那麼資源洩漏的概率就會大大降低,因為棧物件可以自動釋放資源,即使是再所在函式發生異常的時候。

實際的過程是這樣的:函式丟擲異常時,會發生所謂的stack_unwinding(堆疊回滾),即堆疊會展開,由於是棧物件,自然存在於棧中,所以在堆疊回滾的過程中,棧物件的析構函式會被執行,從而釋放其所封裝的資源。除非在析構函式執行的過程中再次丟擲異常――而這種可能性是很小的,所以用棧物件封裝資源是比較安全的。基於此認識,就可以建立乙個自己的控制代碼或**來封裝資源了(智慧型指標應該就是使用了這種技術)。

摘自參考部落格

C 記憶體分配

總結 1 從靜態儲存區域分配。內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在。例如全域性變數,static變數。2 在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高,但是...

C 記憶體分配

c 中的記憶體主要分為五塊 全域性區 static 存放全域性變數或靜態變數 常量區 const 存放常量,不允許修改 可以通過特殊手段修改 堆 heap 由使用者自行分配和釋放,在程式執行時分配。由malloc分配,由free釋放 自由儲存區 free store 由new分配,由delete釋放...

C 記憶體分配

在c 中,記憶體分成4個區,他們分別是堆,棧,靜態儲存區和常量儲存區 1 棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變數的儲存區.裡面的變數通常是區域性變數,函式引數等.2 堆,又叫自由儲存區,它是在程式執行的過程中動態分配的,它最大的特性就是動.態性.由new分配的記憶體塊,他...