在C++/Windows中检测内存泄漏

4

为了调试目的,在编写应用程序时,我首先将以下内容放入stdafx.h文件中:

// -- leak detection ----------------------------------------------------------
#ifdef _DEBUG   
// http://msdn.microsoft.com/en-us/library/e5ewb1h3(v=VS.80).aspx
#define _CRTDBG_MAP_ALLOC   
#include <stdlib.h>
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif

然后我在程序的main()函数开头添加了以下内容:

#ifdef _DEBUG
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
//_CrtSetBreakAlloc( 670 );
#endif  

重新定义 new 操作符以提供泄漏信息是一种有用的工具。但是对于 CoTaskMemAlloc 和 CoTaskMemFree 呢?如何使用它们来检测泄漏?
我正在编写使用 COM 和 DirectShow 的软件,需要知道如何跟踪使用 CoTask 分配引起的泄漏。
谢谢!
4个回答

6

摆脱手动内存管理,就能消除内存泄漏。采用RAII,永远不要使用未包装在处理程序中的资源。

我认为我已经好几年没有出现内存泄漏(或崩溃)了。但是过去十年中我只写了不到半打delete


7
那几乎是一个毫无帮助的评论。 - user206705
1
@freefallr,这怎么可能是“几乎没有帮助”的呢?除非你有非常特殊的需求,无法使用RAII(你从未提到过,所以人们会认为你不知道这种技术),否则它确实可以帮助你防止内存泄漏,这也是检测它们的目的吧?当然,它并没有直接回答你的问题,但它确实提供了一种通常更好的解决方法,不是吗? - blwy10
@sbi:不同之处在于,你可以通过避免再次折断它们来修复你的骨头,而重构你的代码以使用RAII将修复你的内存泄漏问题,这无疑是非常值得的。 - Puppy
你看起来比我更有经验。但是那些似乎更坚定地争论并支持他们最初模糊的陈述的人是没有帮助的,只会把对话线索引向不可避免的争论。这有什么用处吗?!我的程序从网络源接收媒体帧。这些媒体帧必须传递给第三方(MainConcept)提供的DirectShow过滤器,因此(i)该过滤器是一个黑盒子,(ii)我认为该过滤器没有像应该一样释放媒体帧,以及(iii)DirectShow过滤器必须接收通过CoTaskMemAlloc分配的媒体帧。 - user206705
4
总体而言,我同意这里的 SBI。采用 RAII 技术。话虽如此,仍然有可能因为各种原因导致内存和资源泄漏。此时你可以使用像 Deleaker 这样的工具:http://www.deleaker.com/index.html。但是,通常我所做的是使用 detours 库来挂接到相关的函数,并自己跟踪资源。 - Just another metaprogrammer
显示剩余5条评论

4

v1.9在我的VS10上无法工作,但是从这里下载的v2.2.3却完美运行。 - user136776

1

0
但是CoTaskMemAlloc和CoTaskMemFree怎么办?我如何使用它们来检测泄漏?
出于与malloc/free相同的原因,您无法使用它们来检测泄漏。您需要适当地包装它们以帮助您进行泄漏检测。
正如其他帖子所说,如果您担心泄漏,请从头开始设计应用程序,并考虑此要求。在可以管理/跟踪分配/释放的位置使用自定义分配器。
您是否访问过这个问题:CoTaskMemAlloc的用法?

我并不是想要使用这些调用来检测泄漏,如果我的陈述不清楚,对此我很抱歉。我只是想要检测可能由CoTask调用分配的内存泄漏。 - user206705
我的程序从网络源接收媒体帧。这些媒体帧必须传递给由第三方(MainConcept)提供的DirectShow过滤器。因此,(i) 过滤器是一个黑盒子,(ii) 我认为过滤器没有像应该做的那样释放媒体帧,(iii) Directshow过滤器必须接收通过“COM-aware”CoTaskMemAlloc分配的媒体帧。基本上,虽然我可以分配帧,但要由第三方组件处理释放。我希望能够证明第三方组件没有正确释放。 - user206705
这是糟糕的设计。良好设计的一个基本原则是分配资源的人负责释放资源。由于释放操作在不同的库中,你的生活并不十分美好。我建议尝试证明第三方库实际上确实释放了所有框架,在 WinDbg 中设置 CoTaskMemFree 断点,等待看看当我在第三方库内部时是否会命中该断点。 - dirkgently

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接