科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件Visual C++中检测和隔离内存泄漏

Visual C++中检测和隔离内存泄漏

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

具有动态的分配和释放内存的能力是C/C++程序语言的重要特色之一。VisualC++ debugger和CRT库提供了一系列有效的检测和鉴定内存泄漏的工具。

作者:教程网 来源:教程网 2007年9月14日

关键字: Visual C++ 内存泄漏 软件

  • 评论
  • 分享微博
  • 分享邮件

具有动态的分配和释放内存的能力是C/C++程序语言的重要特色之一。VisualC++ debugger和CRT库提供了一系列有效的检测和鉴定内存泄漏的工具。

设置内存泄漏检测

检测内存泄漏的基本工具是调试器和CRT调试堆函数。为了使用调试堆函数,在你的程序中你必须含有下面的说明:

#define _CRTDBG_MAP_ALLOC

#include

#include


必须保证上面声明的顺序,如果改变了顺序,可能不能正常工作。的_malloc_dbg和_free_dbg将取代标准的malloc和free函数出现在DEBUG版中,它可以跟踪内存的分配和释放。但是这只会在DEBUG版本中发生(当#define _DEBUG的时候),而Release版本仍使用标准的malloc和free功能。

#define _CRTDBG_MAP_ALLOC表示使用CRT堆函数的相应的DEBUG版本。这个定义不是必须的,但是没有它,内存泄漏报告含有的只是没有什么用处的信息。

一旦你已经添加了刚才的声明,你就能够通过在程序中加入下面的代码来报告内存泄漏信息:

_CrtDumpMemoryLeaks();


当在DEBUG模式下运行程序时,在Output窗口的Debug标签处_CrtDumpMemoryLeaks会显示内存泄漏的信息,例如:

Detected memory leaks!

Dumping objects ->

C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18} normal block at 0x00780E80, 64 bytes long.

Data:< > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

Object dump complete.


如果没有#define _CRTDBG_MAP_ALLOC,内存泄漏报告就会像下面这样:

Detected memory leaks!

Dumping objects ->

{18} normal block at 0x00780E80, 64 bytes long.

Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

Object dump complete.



由此可见,定义_CRTDBG_MAP_ALLOC时,_CrtDumpMemoryLeaks可以提供更多的有用信息。

如果没有定义_CRTDBG_MAP_ALLOC,那么内存泄漏报告如下显示:

 内存分配数值(花括号内)

 模块的类型(normal、client或者CRT)

 以十六进制格式定位的内存

 以字节计模块的大小

 第一个十六字节的内容(也可以用十六进制)

如果定义了_CRTDBG_MAP_ALLOC,报告的内容还包括出现分配所泄漏内存的文件。在文件名之后括号内的数字是文件内的行数值。

此时双击包含行数值和文件名的输出行, 或者选择输出行并按F4:

C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18} normal block at 0x00780E80, 64 bytes long.

编辑窗口将会跳到文件中分配所泄漏内存的那一行代码,leaktest.cpp中的行号为20的那一行。

使用_CrtSetDbgFlag

如果你的程序只在一个地方退出,那么在选择调用_CrtDumpMemoryLeaks的位置是非常容易的。但是,如果你的程序可能会在程序多处位置退出该怎么办?如果不希望在每一个可能的出口处调用_CrtDumpMemoryLeaks,那么你可以在你的程序开始处包含下面的调用:

_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

当程序退出时,将会自动地调用_CrtDumpMemoryLeaks(必须设置_CRTDBG_ALLOC_MEM_DF和 _CRTDBG_LEAK_CHECK_DF)。

翻译内存模块的类型



内存泄漏报告中把每一块泄漏的内存分为普通块、客户块和CRT块。事实上,你只需要留心普通块和客户块类型。

普通块(normal block):是由你的程序分配的内存。

客户块(client block):是一种特殊的内存块,它是由MFC使用的一个对象,程序退出时,该对象的析构函数没有被调用。MFC new操作符可以用来创建普通块和客户块。

CRT块(CRT block):是由C RunTime Library供自己使用而分配的内存块。CRT库自己来管理这些内存的分配与释放,通常你不会在内存泄漏报告中发现有CRT内存泄漏,除非程序发生了严重的错误(例如CRT库崩溃)。

下面这两种类型的内存块不会出现在内存泄漏报告中:

 空闲块(free block):已经被释放(free)的内存块。

 忽略块(Ignore block):是程序员显式声明过不要在内存泄漏报告中出现的内存块

设置CRT报告样式

通常_CrtDumpMemoryLeaks()会dump内存泄漏的信息到output窗口的Debug栏位。你可以使用_CrtSetReportMode()来重新设置输出到另一个位置。关于更详细的如何使用_CrtSetReportMode()说明,请查看MSDN。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章