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

VC++ CRT 調試堆檢測內存洩漏完全指南

     編輯:VC++

啟用內存洩漏檢測

在項目預編譯頭 stdafx.h 最頂部添加(順序不可變):

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

_CRTDBG_MAP_ALLOC 將 malloc/free 映射到調試版 _malloc_dbg/_free_dbg,記錄文件/行號。僅 Debug 構建生效 (_DEBUG 定義時)。

輸出洩漏報告

在程序退出點調用:

_CrtDumpMemoryLeaks();

或在程序入口設置標志(自動在退出時調用):

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

解讀輸出信息

Detected memory leaks!
Dumping objects ->
C:\Project\test.cpp(15) : {45} normal block at 0x00441BA0, 2 bytes long.
Data: <AB> 41 42
  • {45}:分配序號(程序啟動以來第 45 次分配)。
  • normal block:塊類型——normal(用戶代碼), client(MFC 對象), CRT(運行庫內部)。
  • at 0x...:內存地址。
  • 2 bytes long:大小。
  • Data: ...:前 16 字節十六進制內容。
  • 關鍵:有 _CRTDBG_MAP_ALLOC 時顯示文件名與行號 (test.cpp(15)),雙擊可直接跳轉源碼。

設置分配序號斷點定位洩漏上下文

在監視窗口輸入:

_crtBreakAlloc          // 單獨 CRT 靜態庫
{,,msvcrtd.dll}_crtBreakAlloc  // 使用 CRT 動態庫 (/MDd)

將值改為洩漏報告中的序號 (如 45)。程序運行到第 45 次分配自動中斷,查看調用堆棧確定具體業務邏輯與條件。

或在代碼中硬編碼:_crtBreakAlloc = 45; / _CrtSetBreakAlloc(45);。

內存狀態快照比較法

適用於定位某代碼段洩漏:

_CrtMemState s1, s2, s3;
_CrtMemCheckpoint(&s1);          // 快照 1
// ... 疑似洩漏代碼 ...
_CrtMemCheckpoint(&s2);          // 快照 2
if (_CrtMemDifference(&s3, &s1, &s2)) {
    _CrtMemDumpStatistics(&s3);  // 輸出差異統計
}

輸出示例:

75 bytes in 3 Normal Blocks.
5037 bytes in 41 CRT Blocks.
Largest number used: 5308 bytes.
Total allocations: 7559 bytes.

若 Normal Blocks 增長且未釋放,即為洩漏。可二分法縮小範圍定位具體函數。

內存塊類型完整分類

類型來源是否出現在洩漏報告
Normal用戶 new/malloc是
ClientMFC new (帶析構對象)是
CRT運行庫內部極少 (除非 CRT 崩潰)
Free已釋放塊否
Ignore用戶標記忽略 (_CrtSetDbgFlag)否

報告輸出重定向

默認輸出到「輸出」視窗 Debug 頁。若被其他庫劫持,可恢復:

_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);

總結

CRT 調試堆提供了零成本、無需第三方工具的強大洩漏檢測能力。結合 _CrtDumpMemoryLeaks、分配序號斷點、內存狀態差異比較,可高效定位 99% 的內存洩漏問題。MFC 項目同樣適用。

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