C 可能存在的記憶體洩漏問題 個人經驗總結

2021-10-07 08:25:17 字數 1571 閱讀 3652

1.幾乎所有程式設計師都知道的,使用new申請的記憶體,已不再使用卻沒被delete;

破解之道:

方法很多,

最基礎方法就是程式設計師自己注意 new 和 delete 配套出現;

比較高階一點的,就是模仿智慧型指標,使用引用計數器;

2.new出來的記憶體,被強轉成其他型別,之後被釋放,但記憶體並沒有被清理乾淨;

比如:(示例偽**,不追求可執行)

class student

class person

void main()

3.申請時使用 new,但釋放時使用 delete;

破解之道:

(new -- delete)

(new -- delete )

4.比較不好排查的一種情況

示例,偽**,不追求可執行性

class base

class person:public base

void main()

簡單分析:

person繼承base基類,所以person記憶體中至少存在8位元組(int a + int b),

而base* p = new person;是合法的,

delete p;也是合法的,

問題在於 delete p 時,只釋放了base中的資源,也就是(int a)資源,

導致派生類中(int b)資源意外丟失。

解決方法:

使用 虛析構函式

class base

class person:public base

5.比較少見的情況

示例:偽**,不追求可執行性

class test

void main()

簡單分析:

memcpy(&a,&b,sizeof(a));

首先要知道 test.p 也是4位元組的資料塊,只不過這裡存放的是另一塊記憶體的起始位址,

由於完全拷貝,導致指標 a.p = b.p ,

也就是說原先 a.p 中存放的位址被 b.p 位址覆蓋,

使得原先 a.p 所指向的記憶體無法再被訪問到;

破解之道:

當然是禁止對類例項進行memcpy,memset這類操作啦!

6.更稀少的情況:析構函式中丟擲異常導致記憶體洩漏

class test

}呼叫:

std::vectorvtest;

簡單分析:

vtest容器物件被銷毀之前,會先銷毀內部的test物件例項,但test析構函式在執行過程中,

因為某些原因,丟擲異常,導致記憶體未被完全釋放,甚至會引發程式後續一系列不明確行為;

破解之道:

不要在析構函式中丟擲異常,

如果出現異常,可考慮使用std::abort強制中斷程式,

更仁道的做法,是捕捉異常,但可能會有不良的執行後果,

具體如何抉擇,視情況而定,

但是,但是,但是,最好的方法,當然是禁止在析構函式中丟擲異常;

C 中可能會出現記憶體洩漏的情況

1.new之後沒有呼叫對應的delete 2.呼叫了delete但是delete沒有執行,比如說delete在for迴圈內部,由於過早的continue,break,goto語句跳過了delete語句。或者由於出現異常導致delete語句沒有執行。3.在有繼承關係的類中,父類的析構函式沒有宣告為vi...

關於c語言的傳參問題個人見解

第一次寫部落格 哈哈,興奮。今天突然發現虛擬機器中突然發現乙個小的測試例子 自己都不記得了,仔細研究了一下我發現我居然是做錯了,好吧 c語言還是不紮實,不過關,雖然工作了一年了,唉 這是乙個關於函式傳參並且考察指標操作的例子,直接上例子 include define ulong unsigned l...

C 記憶體洩漏的常規問題和解決辦法

問題 c 記憶體洩漏 原因 記憶體錯誤和並非問題。1,記憶體洩漏 堆疊記憶體沒有釋放,少量一般無事 大量記憶體洩漏 導致記憶體耗盡,後續分配記憶體失敗,程式奔潰。少量記憶體洩漏 程式執行時間長久,也容易奔潰。2,記憶體越界訪問 1 讀越界,讀取不是自己的資料。讀取位址無效,程式直接奔潰。讀取位址有效...