在VisualC 中检测和隔离内存泄漏
来源:互联网
作者:西部数码
时间:2008-04-09
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!
Object dump complete.
CRT库为在程序运行期间分配的所有内存模块计数,包括CRT自己分配的内存或者诸如MFC等分配的其它模块。因此带有分配号n的一个对象是在你的程序中分配的第n个对象,但不代表是由那段代码分配的第n个对象(在大部分情况下,它都不会是。)
这样的话,你可以利用分配号在内存分配的地方设置一个断点。为了设置这样一个端点,你可以在你的程序开始处,设置一个位置断点。当你的程序在那一点break时,你就能够从QuickWatch对话框或者Watch窗口设置这样一个位置断点。
例如,在Watch窗口中,在Name栏键入下面的表达式:
_crtBreakAlloc
如果你正在用CRT库dynamic-link library (DLL)的多线程版本,你必须含有上下文操作符,像这样:
{,,msvcrtd.dll}_crtBreakAlloc
现在按下RETURN键,调试器找到该值并把结果放置在value栏。如果你在内存分配过程中还没有设置任何内存分配断点,那么这个值是-1。用你想要去中断的内存分配的分配数值来,取代value表中的值——例如,18。
当设置完内存分配断点之后,继续调试。这时,运行程序时一定要小心,要保证内存块分配的顺序不会改变。当你的程序在内存分配点中断的时候,你就能够查看Call Stack窗口和其他的DEBUG信息来分析泄漏原因了。你仍然可以继续从那一点执行程序,以至于了解到底发生了什么,同时确定为什么内存没有被释放(设置一个内存分配断点是很有帮助的)。
虽然在调试器中设置内存分配断点通常更容易,但是如果你喜欢的话,你也可以在你的代码中设置它们。为了在你的代码中设置一个内存分配断点,可以增加这样一行(对于第十八个内存分配):
_crtBreakAlloc = 18;
你还有可以使用有相同效果的_CrtSetBreakAlloc函数:
_CrtSetBreakAlloc(18);
比较内存状态
定位内存泄漏的另一个方法就是在关键点对应用程序的内存状态做快照。CRT库提供了一个结构类型_CrtMemState。你可以用它来存储内存状态的一个快照:
_CrtMemState s1, s2, s3;
为了在特定点对内存状态进行快照,可以传递一个_CrtMemState结构到he _CrtMemCheckpoint函数。此函数用当时内存状态的一个快照来填充此结构:
_CrtMemCheckpoint( &s1 );
你可以通过传递此结构到_CrtMemDumpStatistics函数来dump _CrtMemState结构的任意点的内容:
_CrtMemDumpStatistics( &s1 );
此函数打印出类似于下面这样的一堆内存分配信息:
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用来比较两个内存状态(最后面的那两个参数),并返回状态差异的结果(第一个参数)。在你的函数开始和结尾处的_CrtMemCheckpoint调用和使有_CrtMemDifference来比较结果为检测内存泄漏提供了另一种方法。如果检测到一个泄漏,那么可以使用_CrtMemCheckpoint调用来分割你的程序,并使用binary search technique来定位泄漏。
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!



