VC 2012 中的内存泄漏检测

Memory leaks detection in VC 2012

本文关键字:泄漏 检测 内存 2012 VC      更新时间:2023-10-16

在旧版本的Visual C++中,调试器能够检测到内存泄漏。例如以下代码

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
    char *memleak= new char[100];
    memleak[0]='a';
    return 0;
}

应导致一条消息,指出内存为 100 字节。像这样的东西:(请参阅 MSDN)

检测到内存泄漏! 倾倒对象 -> {18} 0x00780E80的普通块,长度为 100 字节。 数据: <> 光盘 对象转储完成。

但我无法"强迫"这条消息。我必须启用什么吗?还是我必须安装一些额外的功能?我正在使用工作室教授 2012 更新 4。

@Vinzenz的答案有点当场,但我会尝试提供所有细节。您基本上有两个选择 - 要么在程序退出时让调试运行时转储泄漏(这可以通过使用设置了_CRTDBG_LEAK_CHECK_DF位的标志值调用_CrtSetDbgFlag来打开内存泄漏报告来完成),或者如前所述调用_CrtDumpMemoryLeaks()在随机执行点转储泄漏。由于您的示例没有执行这些操作中的任何一项,因此您一无所获。

_CrtDumpMemoryLeaks()重要的是,

它将转储在调用它时尚未释放的堆分配,因此此时任何尚未销毁的智能指针(以及在其中分配堆内存的所有其他对象)都将被转储。这就是为什么使用 report 标志会更好一些,因为它在程序执行结束后运行,因此所有应该销毁的对象都被销毁。

至于 DBG_NEW ,它只为您提供额外的行信息,显示导致泄漏的行。没有它,您将获得输出,就像问题中的示例一样,有了它,您将获得导致此问题的行号(请参阅下面的示例)。

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
/*
Without the DBG_NEW you get something like, no line info
Detected memory leaks!
Dumping objects ->
{74} normal block at 0x00000000005D6520, 100 bytes long.
Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete
With it you get
Detected memory leaks!
Dumping objects ->
strcattest.cpp(36) : {74} normal block at 0x00000000002C6520, 100 bytes long.
Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.
*/
#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
#endif  // _DEBUG
int main(int argc, char* argv[])
{
    // Enable automatic memory leak reporting at the end of the program, the next 3 lines can be skipped if _CrtDumpMemoryLeaks() is called somewhere
    int current_flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG );
    current_flags |= _CRTDBG_LEAK_CHECK_DF; 
    _CrtSetDbgFlag(current_flags);
    char *memleak= new char[100];
    _CrtDumpMemoryLeaks(); // Trigger dumping the leaks at this point
    return 0;
}

您是否通读了那篇 MSDN 文章?使用 new 进行内存分配时,必须添加以下行:

#ifdef _DEBUG   
   #ifndef DBG_NEW      
      #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
      #define new DBG_NEW   
   #endif
#endif  // _DEBUG

您还可以调用_CrtDumpMemoryLeaks(),以在程序的任何点"强制"输出所有检测到的内存泄漏。不过,我更喜欢在我的应用程序的出口点执行此操作。