VC 2012中的内存泄漏检测

时间:2015-01-27 09:16:04

标签: c++ visual-studio-2012 memory-leaks

在旧版本的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字节的memleak。这样的事情:(见MSDN

  

检测到内存泄漏!   转储对象 - &gt;   {18}正常块,位于0x00780E80,长度为100字节。    数据:&lt; &GT; CD CD CD CD CD CD CD CD CD CD CD CD CD CD光盘   对象转储完成。

但我无法“强迫”这条消息。 有什么我必须启用?或者我是否必须安装一些额外的功能? 我正在使用Studio Prof. 2012 Update 4。

2 个答案:

答案 0 :(得分:2)

@Vinzenz的答案有点现场,但我会尝试提供所有细节。您基本上有两个选项 - 在程序退出时使调试运行时转储泄漏(这可以通过使用设置了_CRTDBG_LEAK_CHECK_DF位的标志值调用_CrtSetDbgFlag来打开内存泄漏报告来完成),或者如上所述,调用_CrtDumpMemoryLeaks()将泄漏转储到随机执行点。由于你的例子没有做任何一件事,你什么也得不到。

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

至于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;
}

答案 1 :(得分:1)

您是否阅读过该MSDN文章?在使用new进行内存分配时,必须添加以下行:

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

你也可以致电_CrtDumpMemoryLeaks()来强迫&#34;强迫&#34;在程序的任何位置检测到的所有内存泄漏的输出。我更喜欢在我的应用程序的退出点上执行此操作。