C 中記憶體洩漏的幾種情況

2022-06-28 23:00:17 字數 2150 閱讀 5434

1. 在類的建構函式和析構函式中沒有匹配的呼叫new和delete函式

兩種情況下會出現這種記憶體洩露:一是在堆裡建立了物件占用了記憶體,但是沒有顯示地釋放物件占用的記憶體;二是在類的建構函式中動態的分配了記憶體,但是在析構函式中沒有釋放記憶體或者沒有正確的釋放記憶體

2. 沒有正確地清除巢狀的物件指標3. 在釋放物件陣列時在delete中沒有使用方括號

方括號是告訴編譯器這個指標指向的是乙個物件陣列,同時也告訴編譯器正確的物件位址值病呼叫物件的析構函式,如果沒有方括號,那麼這個指標就被預設為只指向乙個物件,物件陣列中的其他物件的析構函式就不會被呼叫,結果造成了記憶體洩露。如果在方括號中間放了乙個比物件陣列大小還大的數字,那麼編譯器就會呼叫無效物件(記憶體溢位)的析構函式,會造成堆的奔潰。如果方括號中間的數字值比物件陣列的大小小的話,編譯器就不能呼叫足夠多個析構函式,結果會造成記憶體洩露。

釋放單個物件、單個基本資料型別的變數或者是基本資料型別的陣列不需要大小引數,釋放定義了析構函式的物件陣列才需要大小引數。

4. 指向物件的指標陣列不等同於物件陣列

物件陣列是指:陣列中存放的是物件,只需要delete p,即可呼叫物件陣列中的每個物件的析構函式釋放空間

指向物件的指標陣列是指:陣列中存放的是指向物件的指標,不僅要釋放每個物件的空間,還要釋放每個指標的空間,delete p只是釋放了每個指標,但是並沒有釋放物件的空間,正確的做法,是通過乙個迴圈,將每個物件釋放了,然後再把指標釋放了

5. 缺少拷貝建構函式

兩次釋放相同的記憶體是一種錯誤的做法,同時可能會造成堆的奔潰。

按值傳遞會呼叫(拷貝)建構函式,引用傳遞不會呼叫。

在c++中,如果沒有定義拷貝建構函式,那麼編譯器就會呼叫預設的拷貝建構函式,會逐個成員拷貝的方式來複製資料成員,如果是以逐個成員拷貝的方式來複製指標被定義為將乙個變數的位址賦給另乙個變數。這種隱式的指標複製結果就是兩個物件擁有指向同乙個動態分配的記憶體空間的指標。當釋放第乙個物件的時候,它的析構函式就會釋放與該物件有關的動態分配的記憶體空間。而釋放第二個物件的時候,它的析構函式會釋放相同的記憶體,這樣是錯誤的。

所以,如果乙個類裡面有指標成員變數,要麼必須顯示的寫拷貝建構函式和過載賦值運算子,要麼禁用拷貝建構函式和過載賦值運算子

6. 缺少過載賦值運算子

這種問題跟上述問題類似,也是逐個成員拷貝的方式複製物件,如果這個類的大小是可變的,那麼結果就是造成記憶體洩露,如下圖:

7. 關於nonmodifying運算子過載的常見迷思

a. 返回棧上物件的引用或者指標(也即返回區域性物件的引用或者指標)。導致最後返回的是乙個空引用或者空指標,因此變成野指標

b. 返回內部靜態物件的引用。

c. 返回乙個洩露記憶體的動態分配的物件。導致記憶體洩露,並且無法**

解決這一類問題的辦法是過載運算子函式的返回值不是型別的引用,二應該是型別的返回值,即不是 int&而是int

8. 沒有將基類的析構函式定義為虛函式

當基類指標指向子類物件時,如果基類的析構函式不是virtual,那麼子類的析構函式將不會被呼叫,子類的資源沒有正確是釋放,因此造成記憶體洩露

野指標:指向被釋放的或者訪問受限記憶體的指標。

造成野指標的原因:

指標變數沒有被初始化(如果值不定,可以初始化為null)

指標被free或者delete後,沒有置為null, free和delete只是把指標所指向的記憶體給釋放掉,並沒有把指標本身乾掉,此時指標指向的是「垃圾」記憶體。釋放後的指標應該被置為null.

指標操作超越了變數的作用範圍,比如返回指向棧記憶體的指標就是野指標。

**:

C 中記憶體洩漏的幾種情況

1.在類的建構函式和析構函式中沒有匹配的呼叫new和delete函式 兩種情況下會出現這種記憶體洩露 一是在堆裡建立了物件占用了記憶體,但是沒有顯示地釋放物件占用的記憶體 二是在類的建構函式中動態的分配了記憶體,但是在析構函式中沒有釋放記憶體或者沒有正確的釋放記憶體 2.沒有正確地清除巢狀的物件指標...

C 記憶體洩漏的幾種情況

1.在類的建構函式和析構函式中沒有匹配的呼叫new和delete函式 兩種情況下會出現這種記憶體洩露 一是在堆裡建立了物件占用了記憶體,但是沒有顯示地釋放物件占用的記憶體 二是在類的建構函式中動態的分配了記憶體,但是在析構函式中沒有釋放記憶體或者沒有正確的釋放記憶體 2.沒有正確地清除巢狀的物件指標...

Android中記憶體洩漏的幾種情況

1.單例造成的記憶體洩漏 android中單例模式中的餓漢式寫法如下 public class example private static example instance private example context context public static example getinsta...