内存泄漏和内存增长

内存泄漏和内存增长不是同一个问题。

内存增长的现象是运行时内存占用越来越大,这种现象有可能是有意设计的。

内存泄漏是指分配的内存没有释放,导致内存不能归还操作系统。现代的操作系统一般都能在进程结束后回收所有内存。如果是没有这种内存回收机制就只好重启机器了。


VS下检测内存泄漏的方法:

#ifdef _DEBUG
#define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_NEW
#endif
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>

#include <stdlib.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

...
_CrtDumpMemoryLeaks(); // 程序的退出处


输出结果如下:

Detected memory leaks!

Dumping objects ->

{45} normal block at 0x00441BA0, 2 bytes long.
Data: <AB> 41 42

{44} normal block at 0x00441BD0, 33 bytes long.
Data: < C > 00 43 00 CD CD CD CD CD CD CD CD CD CD CD CD CD

{43} normal block at 0x00441C20, 40 bytes long.
Data: < C > C0 01 43 00 16 00 00 00 00 00 00 00 00 00 00 00

Object dump complete.

{xx}:花括弧内的数字是内存分配序号,本文例子中是 {45},{44},{43};
block:内存块的类型,常用的有三种:normal(普通)、client(客户端)或 CRT(运行时);本文例子中是:normal block; 
用十六进制格式表示的内存位置,如:at 0x00441BA0 等;
以字节为单位表示的内存块的大小,如:32 bytes long; 
前 16 字节的内容(也是用十六进制格式表示),如:Data: 41 42 等;

在内存分配序号前面还会显示分配泄漏内存的文件名,文件名后括号中的数字表示发生泄漏的代码行号,比如:

C:\Temp\memleak\memleak.cpp(15)


查看内存分配序号,也可以在内存分配序号处打断点:

{,,msvcr90d.dll}_crtBreakAlloc

{,,msvcr100d.dll}_crtBreakAlloc

注意msvcr90d.dll,msvcr100d.dll是vs2008,vs2010环境使用的运行库dll.

若你用的是其他版本vs,请换成对应版本的dll.

在开始调试程序的时候, 将程序停在入口处, 在Watch窗口中输入{,,msvcr90d.dll}_crtBreakAlloc(),应该可以看到它的值为-1.双击它,输入您想设置断点的内存分配号.F5运行起来. 在内存泄漏的地方{18}, 程序便会遇到断点.这样就可以调试了.  


若要确定某段代码中是否发生了内存泄漏,可以通过获取该段代码之前和之后的内存状态快照,然后使用 _CrtMemDifference 比较这两个状态:

_CrtMemState s1, s2, s3;

_CrtMemCheckpoint( &s1 );// 获取第一个内存状态快照

// 在这里进行内存分配

_CrtMemCheckpoint( &s2 );// 获取第二个内存状态快照

// 比较两个内存快照的差异
if ( _CrtMemDifference( &s3, &s1, &s2) )
_CrtMemDumpStatistics( &s3 );// dump 差异结果


ps:检测内存泄漏的基本原理就是new和delete要匹配,某一个new没有对应的delete就会内存泄漏。

例1:char* p保存了一个new出来的指针,但后来在操作其它变量时由于内存越界等其它原因,将p改写为其它值。那么原来new出来的内存就永远无法释放了;

例2:在一个函数中new出来一个对象,然后利用该对象处理业务,处理结束后delete该对象。但是在处理业务过程中出现异常,那么delete操作就无法调用,内存泄漏了。这个例子是《More Effective C++》中说的,对策是用类指针的对象(例如auto_ptr)包含new出来的对象,则类指针对象的析构函数中会delete在构造函数中new出来的内存。即使出现异常,类指针对象的析构函数也会正常调用;


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值