C 堆記憶體空間詳解 釋放記憶體 記憶體洩露

2021-06-20 19:01:15 字數 1572 閱讀 1869

家裡要來客人了,我們要給客人們泡茶。如果規定只能在確定來幾位客人之前就把茶泡好,這就會顯得很尷尬:茶泡多了會造成浪費,泡少了怕怠慢了客人。所以,最好的方法就是等知道了來幾位客人再泡茶,來幾位客人就泡幾杯茶。

然而,我們在使用陣列的時候也會面臨這種尷尬:

陣列的儲存空間必須在程式執行前申請,即陣列的大小在編譯前必須是已知的常量表示式。空間申請得太大會造成浪費,空間申請得太小會造成資料溢位而使得程式異常。所以,為了解決這個問題,我們需要能夠在程式執行時根據實際情況申請記憶體空間。

在c++中,允許我們在程式執行時根據自己的需要申請一定的記憶體空間,我們把它稱為堆記憶體(heap)空間

我們用操作符new來申請堆記憶體空間,其語法格式為:

new 資料型別[表示式];

其中,表示式可以是乙個整型正常量,也可以是乙個有確定值的整型正變數,

其作用類似宣告陣列時的元素個數,所以兩旁的中括號不可省略。如果我們只申請乙個變數的空間,則該表示式可以被省略,即寫作:

new 資料型別;

使用new操作符後,會返回乙個對應資料型別的指標,該指標指向了空間的首元素。所以,我們在使用new操作符之前需要宣告乙個對應型別的指標,來接受它的返回值。如下面程式段:

int *iptr;//宣告乙個指標

int size;//宣告整型變數,用於輸入申請空間的大小

cin >>size;//輸入乙個正整數

iptr=new int[size];//申請堆記憶體空間,接受new的返回值

我們又知道,陣列名和指向陣列首元素的指標是等價的。所以,對於iptr我們可以認為是乙個整型陣列。於是,我們實現了在程式執行時,根據實際情況來申請記憶體空間。

當乙個程式執行完畢之後,它所使用的資料就不再需要。由於記憶體是有限的,所以它原來佔據的記憶體空間也應該釋放給別的程式使用。對於普通變數和陣列,在程式結束執行以後,系統會自動將它們的空間**。然而對於我們自己分配的堆記憶體空間,大多數系統都不會將它們**。

如果我們不人為地對它們進行**,只「借」不「還」,那麼系統資源就會枯竭,電腦的執行速度就會越來越慢,直至整個系統崩潰。我們把這種只申請空間不釋放空間的情況稱為記憶體洩露(memory leak)

確認申請的堆記憶體空間不再使用後,我們用delete操作符來釋放堆記憶體空間,其語法格式為:

delete 指向堆記憶體首元素的指標;

如果申請的是乙個堆記憶體變數,則delete後的可以省略;如果申請的是乙個堆記憶體陣列,則該不能省略,否則還是會出現記憶體洩露。另外,我們也不難發現,delete後的指標就是通過new獲得的指標,如果該指標的資料被修改或丟失,也可能造成記憶體洩露。

下面我們來看一段程式,實踐堆記憶體的申請和**:(程式8.7)

#include "iostream.h"

int main()

cout <<"這些數的平均值為" 《我們需要記住的是,申請了資源用完了就一定要釋放,這是程式設計師的好習慣,也是一種責任。

那麼,我們能不能來申請乙個二維的堆記憶體陣列呢?事實上,new 資料型別[表示式][表示式]的寫法是不允許的。所以,如果有需要,最簡單的方法就是用乙個一維陣列來代替乙個二維陣列。這就是上一章最後一小段文字的意義所在。

原文:

C 堆記憶體空間詳解 釋放記憶體 記憶體洩露

家裡要來客人了,我們要給客人們泡茶。如果規定只能在確定來幾位客人之前就把茶泡好,這就會顯得很尷尬 茶泡多了會造成浪費,泡少了怕怠慢了客人。所以,最好的方法就是等知道了來幾位客人再泡茶,來幾位客人就泡幾杯茶。然而,我們在使用陣列的時候也會面臨這種尷尬 陣列的儲存空間必須在程式執行前申請,即陣列的大小在...

Linux釋放記憶體空間

linux伺服器執行一段時間後,由於其記憶體管理機制,會將暫時不用的記憶體轉為buff cache,這樣在程式使用到這一部分資料時,能夠很快的取出,從而提高系統的執行效率,所以這也正是linux記憶體管理中非常出色的一點,所以乍一看記憶體剩餘的非常少,但是在程式真正需要記憶體空間時,linux會將快...

Linux釋放記憶體空間

linux伺服器執行一段時間後,由於其記憶體管理機制,會將暫時不用的記憶體轉為buff cache,這樣在程式使用到這一部分資料時,能夠很快的取出,從而提高系統的執行效率,所以這也正是linux記憶體管理中非常出色的一點,所以乍一看記憶體剩餘的非常少,但是在程式真正需要記憶體空間時,linux會將快...