如何忽略_CrtDumpMemoryLeaks的误报内存泄漏?

时间:2010-02-24 03:19:15

标签: c++ memory static memory-leaks

似乎只要有静态对象,_CrtDumpMemoryLeaks就会返回一个误报,声称它正在泄漏内存。我知道这是因为它们在main()(或WinMain)函数之后才会被销毁。但有没有办法避免这种情况?我使用VS2008。

7 个答案:

答案 0 :(得分:11)

我发现如果你告诉它在程序终止后自动检查内存,它会允许考虑所有的静态对象。我正在使用log4cxx和boost,它在静态块中做了很多分配,这修复了我的“误报”...

添加以下行,而不是在main()的开头某处调用_CrtDumpMemoryLeaks:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

有关用法和宏的更多详细信息,请参阅MSDN文章:

http://msdn.microsoft.com/en-us/library/5at7yxcs(v=vs.71).aspx

答案 1 :(得分:1)

不是一个直接的解决方案,但总的来说,我发现在静态初始化时间内尽可能多地分配它是值得的。它通常会导致头痛(初始化顺序,去初始化顺序等)。

如果证明太难,您可以在_CrtMemCheckpoint开头main()_CrtMemDumpAllObjectsSince致电{{1}}(http://msdn.microsoft.com/en-us/library/h3z85t43%28VS.80%29.aspx) 最后。

答案 2 :(得分:1)

1)你说:

  

似乎只要有静态对象,_CrtDumpMemoryLeaks就会返回一个误报,声称它正在泄漏内存。

我不认为这是正确的。 编辑:不会在堆上创建静态对象。 END EDIT: _CrtDumpMemoryLeaks仅涵盖crt堆内存。因此,这些对象不应该返回误报。 但是,如果静态变量本身包含一些堆内存(例如,它们动态地使用operator new()创建成员对象),则另一回事。

2)考虑使用_CRTDBG_LEAK_CHECK_DF以在程序执行结束时激活内存泄漏检查(这里描述:http://msdn.microsoft.com/en-us/library/d41t22sb(VS.80).aspx)。我想即使在静态变量终止后也会进行内存泄漏检查。

答案 3 :(得分:1)

旧问题,但我有答案。我能够以误报和真实内存泄漏的形式分割报告。在我的主要功能中,我初始化内存调试并在应用程序的真正开始时生成实际的内存泄漏(切勿删除pcDynamicHeapStart):

int main()
{   
   _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
   char* pcDynamicHeapStart = new char[ 17u ];
   strcpy_s( pcDynamicHeapStart, 17u, "DynamicHeapStart" );

   ...

我的申请完成后,报告包含

Detected memory leaks!
Dumping objects ->
{15554} normal block at 0x00000000009CB7C0, 80 bytes long.
Data: <                > DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD
{14006} normal block at 0x00000000009CB360, 17 bytes long.
Data: <DynamicHeapStart> 44 79 6E 61 6D 69 63 48 65 61 70 53 74 61 72 74 
{13998} normal block at 0x00000000009BF4B0, 32 bytes long.
Data: < ^              > E0 5E 9B 00 00 00 00 00 F0 7F 9C 00 00 00 00 00 
{13997} normal block at 0x00000000009CA4B0, 8 bytes long.
Data: <        > 14 00 00 00 00 00 00 00 
{13982} normal block at 0x00000000009CB7C0, 16 bytes long.
Data: <   @            > D0 DD D6 40 01 00 00 00 90 08 9C 00 00 00 00 00

...

Object dump complete.

现在看看“数据:<< strong> DynamicHeapStart >”行。

44 79 6E 61 6D 69 63 48 65 61 70 53 74 61 72 74”。

以下所有报告口泄漏均为误报,以上均为真实泄漏。 误报并不意味着没有泄漏(它可能是一个静态链接库,它在启动时分配堆,从不释放堆),但是您无法消除泄漏,这根本没有问题。

自从我发明了这种方法以来,我再也没有泄漏过应用程序了。 我在这里提供此信息,并希望这有助于其他开发人员获得稳定的应用程序。

答案 4 :(得分:0)

您是否可以在每次需要列表时拍摄当前分配的对象的快照?如果是这样,您可以在查找操作中发生的泄漏时从列表中删除最初分配的对象。在过去,我用它来查找增量泄漏。

另一个解决方案可能是对泄漏进行排序,并且只考虑同一行代码的重复项。这应该排除静态变量泄漏。

雅各

答案 5 :(得分:0)

胆碱。如果你确定_CrtDumpMemoryLeaks()在撒谎,那么你可能是正确的。我所看到的大部分涉嫌内存泄漏归因于对_CrtDumpMemoryLeaks()的调用。我完全同意以下内容; _CrtDumpMemoryLeaks()转储所有打开的句柄。但是你的程序可能已经有了打开的句柄,所以一定要在所有句柄都被释放后调用_CrtDumpMemoryLeaks()。有关详细信息,请参阅http://www.scottleckie.com/2010/08/_crtdumpmemoryleaks-and-related-fun/

答案 6 :(得分:0)

我可以推荐Visual Leak Detector(它是免费的),而不是使用VS内置的东西。我的问题是将_CrtDumpMemoryLeaks与开放源代码库一起使用,该库创建了990行输出,据我所知,所有误报都是来自boost的。 VLD忽略了这些错误,并正确报告了我为测试添加的一些泄漏,包括从C#调用的本机DLL中。