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

淺談 C/C++ 記憶體洩漏(二):偵測工具與 VC 內建機制深度解析

     編輯:VC++

記憶體洩漏偵測核心原理

關鍵在於攔截記憶體配置與釋放函式。每次成功配置將指標加入全域清單,釋放時移除。程式結束時清單殘留指標即為洩漏記憶體。詳細演算法可參考 Steve Maguire《Writing Solid Code》。

三大主流偵測工具類別

  1. MS C-Runtime Library 內建偵測:免費、整合度高,但功能較弱,僅限堆疊記憶體(malloc/free/new/delete),無法偵測系統資源(HANDLE/GDI/BSTR)洩漏,且需原始碼配合(修改舊專案麻煩)。
  2. 外掛式工具:Purify、BoundsChecker 等。功能全面、穩定性關鍵。作者推薦 BoundsChecker(NuMega 出品,穩定可靠)。
  3. Windows Performance Monitor:無法定位程式碼行號,但能偵測隱式洩漏存在,為其他兩類工具無法企及。

VC/MFC 內建偵測機制深度剖析

DEBUG 模式編譯 MFC 專案會自動加入偵測碼。程式結束時 Debug 視窗輸出洩漏資訊:

E:\TestMemLeak\TestDlg.cpp(70) : {59} normal block at 0x00881710, 200 bytes long.
Data: <abcdefghijklmnop> 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70

第一行顯示檔案、行號、配置序號、位址、大小;第二行顯示前 16 位元組內容。

常見誤區:以為是 MFC 提供,實為 MS C-Runtime Library Debug Function

MFC 只是封裝利用。非 MFC 專案同樣可用。關鍵在於 AppWizard 產生的巨集定義:

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

DEBUG_NEW 定義於 afx.h:#define DEBUG_NEW new(THIS_FILE, __LINE__)。經巨集展開後,new char[200] 變為 new(THIS_FILE, __LINE__) char[200],編譯器尋找 operator new(size_t, LPCSTR, int),最終呼叫 _malloc_dbg 記錄檔名行號。

THIS_FILE 優化目的

避免同一 .cpp 多處 new 產生重複常數字串,僅生成一個字串常數,其餘處用指標引用,減小目的檔體積。

非 MFC 專案啟用偵測

int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(tmpFlag);

程式結束時會輸出洩漏資訊,但缺乏檔名行號(除非自行實作類似 MFC 的巨集映射)。

C-Runtime 偵測的局限性

  • 僅限 malloc/realloc/strdup 等 CRT 配置的堆疊記憶體
  • 無法偵測 HANDLE、GDI Object、VARIANT、BSTR 等系統資源洩漏
  • 需原始碼配合巨集,調試舊專案不便

大型專案開發需搭配外掛工具(如 BoundsChecker)彌補不足。

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