使用简单介绍

    在敲代码的过程中。难免会遇到内存泄露的时候。这个时候假设手工查找内存泄露,不说方法没有通用的,就是真的要自己手工查找也是非常耗时间和精力的。诚然。我们能够借助一些工具,并且我们还会惊奇地发现这些工具非常实用(比方Intel的内存泄露检測工具)。可是由于往往这些工具安装比較麻烦,而我们写的程序又不是非常大,所以我们也许能够找个更小巧的方法。微软就提供了这个方案。我们仅仅须要在程序中加入几行代码,就能够发现内存泄露的问题,然后我们就能够定位内存泄露了(自己用几行代码就能够实现,奇妙!

)。那么怎样实现了,基本的几个函数现先列举一下:_CrtDumpMemoryLeaks,_CrtMemCheckpoint,_CrtMemDifference

  • CrtDumpMemoryLeaks :当前全部没有销毁的对象(没有delete和free),默认情况下输出到调试窗体
  • _CrtMemCheckpoint:保存当前全部没有销毁的对象的状态
  • _CrtMemDifference:比較两个_CrtMemCheckpoint保存的状态。返回差异值

  简单的使用_CrtDumpMemoryLeaks能够检測当前没有释放的对象。可是假设程序大一点。须要确定某一段程序是否有问题时,就须要后面的两个參数了。_CrtMemCheckpoint保存的是_CrtDumpMemoryLeaks的结果。假设我们在一段程序的前后分别保存一个状态,那么通过比較这两个状态我们就能够获知这一段程序是否有内存泄露的问题了。

使用演示样例

  • 启用内存泄露调试支持
    #define _CRTDBG_MAP_ALLOC
    #include <stdlib.h>
    #include <crtdbg.h>

    当中#define 语句将 CRT 堆函数的基础版本号映射到相应的调试版本号。 假设省略 #define 语句。内存泄漏转储将有所简化。

使用这些语句启用调试堆函数之后,能够在某个应用程序退出点之前设置一个对 _CrtDumpMemoryLeaks 的调用,以便在应用程序退出时显示内存泄漏报告:
_CrtDumpMemoryLeaks();

假设要为程序加入退出点时检測内存泄露,则能够通过设置调试选项来设置。而不须要在每一个退出点自己加入函数_CrtDumpMemoryLeaks的调用:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

默认情况下,输出的调试信息会在调试窗体。当然,你能够通过_CrtSetReportMode等来自己定义输出位置。
	_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );

为了使得输出的内存泄露信息中包括源码的文件和行信息,还须要定义一些额外的东西,下面是我封装好的头文件,在每一个须要检測内存泄露的文件里包括该头文件就可以:
#ifndef __MEM_LEAN_DETECT_H__
#define __MEM_LEAN_DETECT_H__ #define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define new new( _CLIENT_BLOCK, __FILE__, __LINE__) #endif

当中 #define _CRTDBG_MAP_ALLOC 语句将 CRT 堆函数的基版本号映射到相应的“Debug”版本号。

并不是绝对须要该语句,但假设没有该语句,内存泄漏转储包括的实用信息将较少。


#define new 利用了在源码中获代替码所在文件及行数的方法用以输出内存泄露源所在的代码位置。

  • 比較内存泄露状态

定位内存泄漏的还有一种技术涉及在关键点相应用程序的内存状态拍快照。

若要为应用程序中给定点的内存状态拍快照,创建 _CrtMemState 结构。将它传递给 _CrtMemCheckpoint 函数:

_CrtMemState s1;
_CrtMemCheckpoint( &s1 );

_CrtMemCheckpoint 会将当前内存状态填充在该结构中。
假设要查看输出 _CrtMemState 结构的内容。可使用_ CrtMemDumpStatistics 函数:

_CrtMemDumpStatistics( &s1 );

//_ CrtMemDumpStatistics 输出内存状态转储,例如以下所看到的:
// 0 bytes in 0 Free Blocks.
// 0 bytes in 0 Normal Blocks.
// 3071 bytes in 16 CRT Blocks.
// 0 bytes in 0 Ignore Blocks.
// 0 bytes in 0 Client Blocks.
// Largest number used: 3071 bytes.
// Total allocations: 3764 bytes.

若要确定在某个代码部分中是否发生了内存泄漏,能够对这部分之前和之后的内存状态拍快照,然后使用 _ CrtMemDifference 比較两个状态:

_CrtMemCheckpoint( &s1 );
// memory allocations take place here
_CrtMemCheckpoint( &s2 ); if ( _CrtMemDifference( &s3, &s1, &s2) )
{
_CrtMemDumpStatistics( &s3 );
}

_CrtMemDifference比較内存状态 s1 和 s2,在 (s3) 中返回结果,即 s1 与 s2 的差异。
寻找内存泄漏的一个方法是,首先在应用程序的开头和结尾部分放置 _CrtMemCheckpoint 调用,然后使用 _CrtMemDifference 比較两个结果。 假设 _CrtMemDifference 显示有内存泄漏。通过加入很多其它 _CrtMemCheckpoint 调用来使用二进制搜索划分程序,直至找到泄漏源。

  • 贴几张自己使用的结果图

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYXJiYm90ZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" style="font-size:18px;" />

默认输出的结果

输出代码信息的结果(注意源文件名称和行号)

把内存泄露检測结果自己定义输出到屏幕

最新文章

  1. 关于使用flexible.js自适应页面,发现文字很多时,字体会变大的问题的原因和解决方案
  2. Http请求之--C#的HttpWebRequest实现POST方式请求
  3. div背景图片叠加
  4. Linux里设置环境变量的方法(export PATH)
  5. mac下安装apache+php+mysql
  6. WEB服务器、应用程序服务器、HTTP服务器区别(转)
  7. 火炬之光模型导出(Unity载入火炬之光的模型)
  8. Face-landmarks-detection-benchmark 人脸特征定位网站汇总
  9. swift 注意事项 (十六) —— 可选链
  10. 移动端touch事件获取clientX, clientY
  11. (Android自定义View)来来来,一起再撸一个Material风格loadingView。
  12. 【一天一道LeetCode】#118. Pascal&#39;s Triangle
  13. 非对称加密算法-RSA算法
  14. CSS 标签选择器
  15. navicat 链接 mysql 报错1251
  16. TerraGate SFS Manager配置时权限设置问题
  17. 测试开发之前端——No8.HTML5中的媒介事件
  18. AutoPlay Menu Builder入门教程
  19. yii2的Console定时任务创建
  20. shell read

热门文章

  1. 点击CheckBox让Gridview控件在编辑与正常状态之间切换
  2. MVC会员注销功能Cookie的应用
  3. VS比较好用的扩展插件总结
  4. Mac下,(OS系统)IDEA 逆向工程,生成 hibernate 映射文件以及对应的javaBean(类似于eclipse)
  5. Saving HDU(hdu2111,贪心)
  6. Vue脚手架
  7. JSON: jasckson 字段 过滤
  8. Python 初识网络
  9. 优雅高效的免费在线APP原型工具
  10. 一个关于A标签和分页的怪问题!