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