use*_*906 8 c++ memory-leaks visual-c++ visual-leak-detector
我想在Windows中检测我的C++程序的内存泄漏.我也在MSDN上阅读有关mermoy泄漏检测的文档,我也开始使用Visual Leak Detector.
我对泄漏的报告有疑问.我期待一个带行号的文件名,但我总是报告下面的文字.它包含泄漏描述的所有组件(块类型,内存地址,数据等),但文件名和行号除外.
如果是真正的泄漏?如果是,您知道为什么不报告文件/行吗?与此同时,我也在看这个网址
谢谢
Detected memory leaks!
Dumping objects ->
{4723} normal block at 0x04AFB5B8, 8 bytes long.
 Data:  2C 3F 00 00 28 3F 00 00 
{1476} normal block at 0x04AC3B58, 12 bytes long.
 Data:  00 CD CD CD EB 01 75 4C CA 3D 0B 00 
Object dump complete.
    我研究了一些跟踪内存泄漏的不同方法.他们都有自己的优势,但也有缺点.
要了解它们的优缺点,我们必须了解不同的机制和要求:
如何拦截new,delete,malloc和free?有些工具使用#define重新定义new,delete,malloc和free,但这依赖于包含文件的正确顺序,如果一个类包含例如一个名为free的方法(如Qt中的情况),则可能会出现问题.预处理器还将重新定义此方法,这可能导致编译错误或未解析的外部.
另一种方法是否决全局new和delete运算符.这是一个更清洁的解决方案,但失败的是你有一个第三方库,在库中放置一个新的,但在标题中删除(反之亦然).
如何确定呼叫的来源.如果new,delete,...是使用#define截取的,通常是预处理程序符号__FILE__,__LINE__用于获取泄漏源.但是,如果您的代码中有'通用'函数,例如CreateString(),那么大多数泄漏将在这些通用函数中报告,这对您没有任何帮助.
另一种方法是在运行时获取调用堆栈.使用Windows StackWalk功能可以很容易地完成,但根据我的经验,这非常非常慢.更快的替代方法是直接获取基指针,并依赖堆栈帧指针(必须使用/ Oy-编译才能获得堆栈帧指针).您可以像这样获得帧(基础)指针:_asm mov DWORD PTR [FramePtr], ebp.然后简单地循环并在循环中获取指令指针((ADDR *)FramePtr)[1];和来自的下一个帧指针FramePtr   = ((ADDR *)FramePtr)[0];
如何在确切时刻报告泄漏情况.在我的情况下,我希望在应用程序结束时报告泄漏,但是为了能够执行此操作,您需要在应用程序结束时使用泄漏报告机制.这意味着如果您想自己报告泄漏,则需要依赖于在应用程序结束时被破坏的全局变量(并报告全局变量的析构函数中的泄漏).对于服务器类型的应用程序,您可能更感兴趣的是在两个时间点之间获得内存使用量的差异.
现在不同的泄漏系统:
C RunTime:最后报告泄漏,但没有报告调用堆栈的好方法.它拦截对new,delete,...的调用的方法可能会导致与第三方库(如Qt,Boost,...)组合的问题
外部Microsoft实用程序(如GFlags,UMDH,......):它们似乎只能记录两个时间点之间的差异.但是,调用堆栈似乎要好得多,尽管GFlags实用程序可能会在操作系统中设置可能导致应用程序严重减速的标志.
视觉泄漏探测器.似乎正确找到所有泄漏,但在我的情况下,它不起作用,因为我有一个第三方DLL只是在其DllUnload中断过程(似乎是Windows 7特定的问题).
我个人的最爱(人们不会同意我,我敢肯定),就是写自己的记忆管理员.使用全局new和delete运算符(可能存在上述问题)可以轻松完成拦截,并且可以按上述方法获取调用堆栈.此替代方案还依赖于能够在应用程序的最后一刻执行代码.
在选择替代方案时,我发现以下几个方面对我的情况非常重要:
希望这可以帮助.