【问题标题】:Memory leaks detection in VC 2012VC 2012 中的内存泄漏检测
【发布时间】:2015-03-25 20:25:24
【问题描述】:

在旧版本的 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

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      @Vinzenz 的回答有点到位,但我会尽量提供所有细节。您基本上有两个选择 - 要么在程序退出时使调试运行时转储泄漏(这可以通过调用 _CrtSetDbgFlag 并使用具有 _CRTDBG_LEAK_CHECK_DF 位设置的标志值来打开内存泄漏报告来完成),或者作为提到调用_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;
      }
      

      【讨论】:

      • 感谢您的详细回答...现在我想知道为什么它使用旧版本:-/
      • @nobs 旧版本是什么意思?
      • 我们使用了具有相同代码的 VS 2005 我们收到了消息。不知道有什么变化,但我不会再挖旧版本了
      猜你喜欢
      • 2012-07-16
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 2012-01-22
      • 2015-02-28
      • 2013-11-14
      相关资源
      最近更新 更多