首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 內存洩露調試定位:MFC 對話框資源釋放檢查

     編輯:程式設計綜合問答

Visual C++ 調試輸出顯示內存洩露,堆棧指向 MFC 內部對話框創建代碼。本文說明如何定位業務代碼中的洩露源頭。

現象

Detected memory leaks!
Dumping objects ->
{123} normal block at 0x00ABCDEF, 48 bytes long.
Data: <...> CD CD CD CD ...
Object dump complete.

堆棧多為 CDialog::DoModal、CWnd::CreateDlgIndirect 等 MFC 內部框架代碼。

核心排查思路

  1. 關注業務代碼中的對話框類:框架代碼只是載體,洩露源頭在你派生的對話框類中
  2. 檢查 OnInitDialog / 構造函數中分配的資源:
    • new 出來的對象是否在 OnDestroy/析構函數中 delete
    • GDI 對象(筆刷、字體、位圖、DC)是否 DeleteObject/ReleaseDC
    • 動態創建的子控件/子對話框是否正確銷毀
  3. 檢查模態對話框返回後的清理:
    MyDialog dlg;
    if (dlg.DoModal() == IDOK) {
      // 處理數據
    }
    // dlg 此處離開作用域自動析構,但成員指針指向的堆內存需手動釋放
  4. 使用 CRT 調試鉤子定位分配點:
    #define _CRTDBG_MAP_ALLOC
    #include 
    #include 
    
    // 程序入口處
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    // 某次可疑分配斷點
    // _CrtSetBreakAlloc(123); // 分配序號

常見洩露模式

代碼模式修正
CBrush* p = new CBrush(...); 無 delete用 CBrush brush(...) 棧對象,或析構刪除
CDC* pDC = new CDC(); 無 delete pDC用 CClientDC dc(this) 棧對象
動態創建控件 new CButton() 無父窗口管理父窗口銷毀時自動銷毀子窗口,或手動 DestroyWindow

工具推薦

  • Visual Leak Detector (VLD):免費、輕量、VS 集成好
  • Deleaker:商業、支持遠程調試
  • Dr. Memory / Valgrind (Linux)

內存洩露雖報在框架,根因在業務。善用 _CrtSetBreakAlloc 定位分配點,對症下藥。

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