热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

VS中检测内存泄漏的方法

vs中检测内存泄漏的方法分类:MFC2013-03-0821:442764人阅读评论(0)收藏举报使用vs的内存检测有以下几种方法。在debug模式下以F5运行:方法一:[html

vs中检测内存泄漏的方法
分类: MFC

使用vs的内存检测有以下几种方法。

在debug模式下以F5运行:

方法一:

[html] view plaincopy
 
  1. #define CRTDBG_MAP_ALLOC    
  2. #include <stdlib.h>    
  3. #include <crtdbg.h>    
  4. //在入口函数中包含 _CrtDumpMemoryLeaks();    
  5. //即可检测到内存泄露  
  6.   
  7. //以如下测试函数为例:  
  8. int main()  
  9. {  
  10.     char* pChars = new char[10];  
  11.     _CrtDumpMemoryLeaks();  
  12.     return 0;  
  13. }  

F5运行输出窗口会得到:

Detected memory leaks!
Dumping objects ->
{58} normal block at 0x00341A38, 10 bytes long.
 Data: <          > CD CD CD CD CD CD CD CD CD CD 
Object dump complete.

以上方法没有输出

注意:
1.在VS2010下测试的时候,发现_CrtDumpMemoryLeaks();这句必须放在函数结束处,放在主函数入口处输出窗口不会输出内存泄露信息
2.{}中的数字指明这块内存是程序中总计第几个被申请的,这种方法没有行号和其他信息输出。我们可以定义:

[html] view plaincopy
 
  1. #ifdef _DEBUG  
  2. #define New   new(_NORMAL_BLOCK, __FILE__, __LINE__)  
  3. #endif  
  4.   
  5. #define CRTDBG_MAP_ALLOC    
  6. #include <stdlib.h>    
  7. #include <crtdbg.h>    
  8. //在入口函数中包含 _CrtDumpMemoryLeaks();    
  9. //即可检测到内存泄露  
  10.   
  11. //以如下测试函数为例:  
  12. int main()  
  13. {  
  14.     char* pChars = New char[10];  
  15.     _CrtDumpMemoryLeaks();  
  16.     return 0;  
  17. }  

输出:

Detected memory leaks!
Dumping objects ->
e:\vs2005\stltest\stltest\test.cpp(14) : {58} normal block at 0x00591A38, 10 bytes long.
 Data: <          > CD CD CD CD CD CD CD CD CD CD 
Object dump complete.

方法二:

 

[html] view plaincopy
 
  1. #define CRTDBG_MAP_ALLOC    
  2. #include <stdlib.h>    
  3. #include <crtdbg.h>    
  4. //在入口函数中包含 _CrtDumpMemoryLeaks();    
  5. //即可检测到内存泄露  
  6.   
  7. //定义函数:  
  8. inline void EnableMemLeakCheck()  
  9. {  
  10.     _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);  
  11. }  
  12. //该函数可以放在主函数的任意位置,都能正确的触发内存泄露输出  
  13.   
  14.   
  15. //以如下测试函数为例:  
  16. int main()  
  17. {  
  18.     EnableMemLeakCheck();  
  19.     char* pChars = new char[10];  
  20.     //_CrtDumpMemoryLeaks();  
  21.     return 0;  
  22. }  

输出:

Detected memory leaks!
Dumping objects ->
{58} normal block at 0x004F1A38, 10 bytes long.
 Data: <          > CD CD CD CD CD CD CD CD CD CD 
Object dump complete.

方法三:直接定位指定内存块错误的代码行

单确定了内存泄漏发生在哪一行,有时候并不足够。特别是同一个new对应有多处释放的情形。在实际的工程中,以下两种情况很典型:

创建对象的地方是一个类工厂(ClassFactory)模式。很多甚至全部类实例由同一个new创建。对于此,定位到了new出对象的所在行基本没有多大帮助。
 
COM对象。我们知道COM对象采用Reference Count维护生命周期。也就是说,对象new的地方只有一个,但是Release的地方很多,你要一个个排除。
那么,有什么好办法,可以迅速定位内存泄漏?

答:有。

在内存泄漏情况复杂的时候,你可以用以下方法定位内存泄漏。这是我个人认为通用的内存泄漏追踪方法中最有效的手段。

我们再回头看看crtdbg生成的内存泄漏报告:

Detected memory leaks!
Dumping objects ->
{58} normal block at 0x004F1A38, 10 bytes long.
 Data: <          > CD CD CD CD CD CD CD CD CD CD 
Object dump complete.

除了产生该内存泄漏的内存分配语句所在的文件名、行号为,我们注意到有一个比较陌生的信息:{58}。这个整数值代表了什么意思呢?

其实,它代表了第几次内存分配操作。象这个例子,{58}代表了第58次内存分配操作发生了泄漏。你可能要说,我只new过一次,怎么会是第58次?这很容易理解,其他的内存申请操作在C的初始化过程调用的呗。:)

有没有可能,我们让程序运行到第58次内存分配操作的时候,自动停下来,进入调试状态?所幸,crtdbg确实提供了这样的函数:即 long _CrtSetBreakAlloc(long nAllocID)。我们加上它:

 

 

[html] view plaincopy
 
  1. #define CRTDBG_MAP_ALLOC    
  2. #include <stdlib.h>    
  3. #include <crtdbg.h>    
  4.   
  5. int main()  
  6. {  
  7.     _CrtSetBreakAlloc(58);  
  8.     char* pChars = new char[10];  
  9.     _CrtDumpMemoryLeaks();  
  10.     return 0;  
  11. }  

你发现,程序运行到 char* pChars = new char[10];一句时,自动停下来进入调试状态。细细体会一下,你可以发现,这种方式你获得的信息远比在程序退出时获得文件名及行号有价值得多。因为报告泄漏文件名及行号,你获得的只是静态的信息,然而_CrtSetBreakAlloc则是把整个现场恢复,你可以通过对函数调用栈分析(我发现很多人不习惯看函数调用栈,如果你属于这种情况,我强烈推荐你去补上这一课,因为它太重要了)以及其他在线调试技巧,来分析产生内存泄漏的原因。通常情况下,这种分析方法可以在5分钟内找到肇事者。


PS:在VS2010下使用这两种方法,宏和头文件不用包含也可以正确运行:
#define CRTDBG_MAP_ALLOC  
#include   
#include    


 非MFC程序可以用以下方法检测内存泄露:

1.程序开始包含如下定义:

#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif  // _DEBUG
#define _CRTDBG_MAP_ALLOC
#include
#include
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif  // _DEBUG

2.程序中添加下面的函数:

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);

Debug版本程序运行结束后如有内存泄漏,输出窗口中会显示类似信息:
Detected memory leaks!
Dumping objects ->
g:\programs\test\test.cpp(16) : {51} client block at 0x00385C58, subtype 0, 4 bytes long.
 Data: <    > CD CD CD CD
Object dump complete.

MFC程序内存泄漏检测方法:

1.在 CMyApp 中添加如下三个 CMemoryState 类的成员变量:

#ifdef _DEBUG
protected:
      CMemoryState m_msOld, m_msNew, m_msDiff;
#endif  // _DEBUG

2.在 CMyApp::InitInstance() 中添加如下代码:

#ifdef _DEBUG
      m_msOld.Checkpoint();
#endif  // _DEBUG

3.在 CMyApp::ExitInstance() 中添加如下代码:

#ifdef _DEBUG
      m_msNew.Checkpoint();
      if (m_msDiff.Difference(m_msOld, m_msNew))
      {
            afxDump<<"\nMemory Leaked :\n";
            m_msDiff.DumpStatistics();
            afxDump<<"Dump Complete !\n\n";
      }
#endif  // _DEBUG

Debug版本程序运行结束后如有内存泄漏,输出窗口中会显示类似信息:

Memory Leaked :
0 bytes in 0 Free Blocks.
8 bytes in 1 Normal Blocks.
0 bytes in 0 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 8825 bytes.
Total allocations: 47506 bytes.
Dump Complete !

Detected memory leaks!
Dumping objects ->
g:\programs\chat\chatdlg.cpp(120) : {118} normal block at 0x00D98150, 8 bytes long.
 Data: <        > A8 7F D9 00 01 00 00 00
Object dump complete.

VS中检测内存泄漏的方法


推荐阅读
  • 1.简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?rea ... [详细]
  • 201720181 20155208 《信息安全系统设计基础》第五周学习总结
    2017-2018-120155208《信息安全系统设计基础》第五周学习总结学习目标理解逆向的概念掌握X86汇编基础,能够阅读(反)汇编代码了解ISA(指令集体系结构)理解函数调用 ... [详细]
  • Unity中的事件监听
    Unity3D的uGUI系统的将UI可能触发的事件分为12个类型,即EventTriggerType枚举的12个值。如下图所示:先以PointerClick为例。这个是用于某点点击 ... [详细]
  • Catalyst揭秘 Day1 Catalyst本地解析
    Catalyst本地解析今天开始讲下Catalyst,这是我们必须精通的内容之一:基本概念catalyst是一种解析器引擎,而不仅是sql解析引擎。如果研究下catalyst,可以 ... [详细]
  • 实验十:指针
    #includevoidsplitfloat(floatx,int*intpart,float*fracpart);intmain(void){intintpa ... [详细]
  • C++学习之Visual Studio安装以及首次使用
    一、安装VisualStudio首先下载VisualStudio链接:http:pan.baidu.coms1pLhJt0Z密码:uqyc将.ios文件解压得到以下文件:点击vs_ ... [详细]
  • 自己的macbookPro只有128G的硬盘,存储空间经常不足,终于找到了个大文件,,UsersusrnameLibraryContainerscom.tencent.qqData ... [详细]
  • # 运维小白的成长日记第七天OSI七层传输层/应用层精讲!
    运维小白的成长日记第七天-OSI七层传输层应用层精讲!1、IP提供了点到点的连续接,通过IP地址可以找到目标主机。但是目标主机有很多应用,服务器到底使用哪个应用来响应客户端?通过端 ... [详细]
  • 【二食堂】AlphaScrum Meeting 4
    ScrumMeeting3例会时间:4.1312:0012:30进度情况|组员|昨日进度|今日任务||||||李健|1.主页面的搭建工作issue|1.完成主页搭建2.与后端协商确 ... [详细]
  • 标准ACL配置
    标准ACL的表号是1~99中的一个数字permit|d ... [详细]
  • 问题描述为某音像店开发一个迷你DVD管理器,最多可存6张DVD,实现碟片的管理。管理器具备的功能主要有:1、查看DVD信息。菜单选择查看功能,展示DVD的信息。2、新增DVD信息选 ... [详细]
  • jenkins 邮件配置步骤
    一、进行系统管理中的邮件配置步骤:1、设置ExtendedE-mailNotification二、对构建的job添加邮件发送的步骤: ... [详细]
  • 一个正整数K,给出KMod一些质数的结果,求符合条件的最小的K。例如,K%21,K%32,K%53。符合条件的最小的K23。收起一个正整数K,给出KMod一些质数的结果,求符合条件 ... [详细]
  • classTestBreakContinue{publicstaticvoidmain(String[]args){for(inti1;i ... [详细]
  • MATLAB分布拟合工具箱distributionFitter
    借助MATLAB(R2017b)分布拟合工具箱distributionFitter,我们可以快速地检查数据的分布。可以进行非参数密度估计(核平滑方法)和参数密度估计(Beta分布、 ... [详细]
author-avatar
我们要走下去一直的
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有