vs中检测内存泄漏的方法

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

在debug模式下以F5运行:

方法一:

#define CRTDBG_MAP_ALLOC  
#include <stdlib.h>  
#include <crtdbg.h>  
//在入口函数中包含 _CrtDumpMemoryLeaks();  
//即可检测到内存泄露

//以如下测试函数为例:
int main()
{
	char* pChars = new char[10];
	_CrtDumpMemoryLeaks();
	return 0;
}

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.{}
中的数字指明这块内存是程序中总计第几个被申请的,这种方法没有行号和其他信息输出。我们可以定义:

#ifdef _DEBUG
#define New   new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

#define CRTDBG_MAP_ALLOC  
#include <stdlib.h>  
#include <crtdbg.h>  
//在入口函数中包含 _CrtDumpMemoryLeaks();  
//即可检测到内存泄露

//以如下测试函数为例:
int main()
{
	char* pChars = New char[10];
	_CrtDumpMemoryLeaks();
	return 0;
}

输出:

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.

方法二:

#define CRTDBG_MAP_ALLOC  
#include <stdlib.h>  
#include <crtdbg.h>  
//在入口函数中包含 _CrtDumpMemoryLeaks();  
//即可检测到内存泄露

//定义函数:
inline void EnableMemLeakCheck()
{
	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
}
//该函数可以放在主函数的任意位置,都能正确的触发内存泄露输出


//以如下测试函数为例:
int main()
{
	EnableMemLeakCheck();
	char* pChars = new char[10];
	//_CrtDumpMemoryLeaks();
	return 0;
}

输出:

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)。我们加上它:

#define CRTDBG_MAP_ALLOC  
#include <stdlib.h>  
#include <crtdbg.h>  

int main()
{
	_CrtSetBreakAlloc(58);
	char* pChars = new char[10];
	_CrtDumpMemoryLeaks();
	return 0;
}

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


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


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

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

#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif  // _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#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.

  • 23
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
VS2022内存泄漏检测是指Visual Studio 2022集成开发环境的一项功能,用于帮助开发者检测和解决程序存在的内存泄漏问题。 内存泄漏是指在程序动态分配内存后没有正确释放,导致这些内存空间无法被再次使用,最终导致内存资源的浪费和程序性能下降的情况。内存泄漏问题是软件开发过程常见的一个难题,如果不及时解决,可能会导致程序崩溃甚至系统崩溃。 VS2022内存泄漏检测功能通过在调试过程对程序的动态内存分配和释放进行监测,帮助开发者快速定位和解决内存泄漏问题。当程序执行过程存在内存泄漏时,该功能可以提供一系列的调试工具和报告,帮助开发者追踪到具体的内存泄漏位置和原因。 VS2022内存泄漏检测功能主要包括以下几个方面: 1. 动态内存分配和释放监测:VS2022可以监测程序的动态内存分配和释放操作,对没有正确释放的内存进行标记和跟踪。 2. 内存泄漏报告:当程序存在内存泄漏时,VS2022可以生成相应的报告,包括内存泄漏的具体位置、泄漏的大小等信息,帮助开发者定位问题。 3. 内存泄漏跟踪:在调试过程VS2022可以提供一系列的跟踪工具,帮助开发者追踪到内存泄漏的发生原因,找出造成内存泄漏的代码段。 4. 自动检测和修复:VS2022内存泄漏检测功能可以自动检测程序的潜在内存泄漏问题,并提供修复建议,方便开发者快速解决问题。 总之,VS2022内存泄漏检测功能为开发者提供了一套全面的工具和报告,帮助他们及时发现和解决程序内存泄漏问题,提高程序的性能和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值