首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC++

淺談 C/C++ 記憶體洩漏(一):定義、類型與經典案例

     編輯:VC++

記憶體洩漏:C/C++ 開發者的永恆痛點

對 C/C++ 程式設計師而言,記憶體洩漏是常見且棘手的問題。雖有智慧指標、垃圾回收等技術,但在 C/C++ 領域應用受限。好在現代工具能協助偵測定位。本文系列將系統梳理洩漏定義、分類、偵測工具與實戰技巧。

記憶體洩漏定義

狹義指堆疊記憶體洩漏:程式以 malloc/realloc/new 從堆疊配置記憶體,用畢後未呼叫 free/delete 釋放,導致該記憶體塊無法再被使用。廣義上尚包含系統資源洩漏(Kernel HANDLE、GDI Object、SOCKET、COM Interface 等),嚴重時甚至導致系統不穩,危害性更大。

四大洩漏發生模式

1. 常發性洩漏

特定程式碼路徑重複執行,每次皆洩漏。例:OnPaint 中若 Something() 恆回傳 TRUE,導致 GDI 位圖物件持續洩漏,長時間運行致系統花屏(Win9x 更易暴露)。

2. 偶發性洩漏

僅在特定環境/操作觸發。同樣的 OnPaint 範例,若 Something() 僅特定條件回傳 TRUE,則為偶發性。測試環境與方法對偵測至關重要。

3. 一次性洩漏

程式碼僅執行一次,或因演算法缺陷導致僅洩漏單一記憶體塊。例:Singleton 類別建構函式配置記憶體,解構函式未釋放;或全域指標重複 strdup 卻無最終釋放邏輯。

4. 隱式洩漏

程式持續配置記憶體,直到結束才釋放。嚴格說非洩漏,但伺服器程式長期運行(天/週/月)會耗盡記憶體。例:連線管理類別未在斷線時即時刪除 Connection 物件,導致記憶體持續增長。

經典程式碼案例

// 例一:函數提早返回未釋放
void MyFunction(int nSize) {
    char* p = new char[nSize];
    if (!GetStringFrom(p, nSize)) { MessageBox("Error"); return; } // 洩漏點
    // ... use p ...
    delete p;
}

// 例二:GDI 物件洩漏
void CMyView::OnPaint(CDC* pDC) {
    CBitmap bmp; bmp.LoadBitmap(IDB_MYBMP);
    CBitmap* pOldBmp = pDC->SelectObject(&bmp);
    if (Something()) return; // 未 SelectObject 回 pOldBmp,HBITMAP 洩漏
    pDC->SelectObject(pOldBmp);
}

// 例三:全域字串重複配置無最終釋放
char* g_lpszFileName = NULL;
void SetFileName(const char* lpcszFileName) {
    if (g_lpszFileName) free(g_lpszFileName);
    g_lpszFileName = strdup(lpcszFileName);
}
// 程式結束未 free(g_lpszFileName) → 一次性洩漏

// 例四:伺服器連線管理隱式洩漏
class ConnectionManager {
    list<Connection*> _connlist;
    void OnClientConnected(SOCKET s) { _connlist.push_back(new Connection(s)); }
    void OnClientDisconnected(Connection* pconn) { _connlist.remove(pconn); delete pconn; }
    ~ConnectionManager() { for (auto p : _connlist) delete p; _connlist.clear(); }
};
// 若 OnClientDisconnected 未被呼叫,Connection 物件積壓直到程式結束

危害性比較

一次性洩漏不堆積,危害最小;常發/偶發性會持續堆積;隱式洩漏最隱蔽、最難偵測,對長期運行服務破壞力最大。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved