【问题标题】:Visual Studio 2017 detect memory Leak when using Poco Xml Document使用 Poco Xml 文档时 Visual Studio 2017 检测内存泄漏
【发布时间】:2018-08-28 11:11:20
【问题描述】:

如果我使用 Poco::XML::Document 类,Visual Studio 会在应用程序运行后转储内存泄漏。

我从 Visual Studio 2017 项目模板创建了一个简单的 ConsoleApplication,并将以下代码添加到 Main

#include "pch.h"
#define _CRTDBG_MAP_ALLOC  
#include <stdlib.h>  
#include <crtdbg.h>  
#include <iostream>
#include <Poco/DOM/Document.h>
#include <Poco/DOM/AutoPtr.h>
int main()
{
    Poco::AutoPtr<Poco::XML::Document> pDoc = new Poco::XML::Document;
    std::cout << "Hello World!\n";
    _CrtDumpMemoryLeaks();
    return 0;
}

这是 Visual Studio 中的泄漏转储(我省略了一些部分,因为它真的很大):

{1976} normal block at 0x0130C048, 8 bytes long.
 Data: <, /     > 2C 18 2F 01 00 00 00 00 
{1975} normal block at 0x0130C0F0, 8 bytes long.
 Data: <  /     > 10 18 2F 01 00 00 00 00 
{1974} normal block at 0x0130BD70, 8 bytes long.
 Data: <  /     > F4 17 2F 01 00 00 00 00 
{1973} normal block at 0x0130BE88, 8 bytes long.
 Data: <  /     > D4 17 2F 01 00 00 00 00 

....

{174} normal block at 0x012D87E0, 8 bytes long.
 Data: <        > C4 0B 89 0F 00 00 00 00 
{173} normal block at 0x012DB928, 32 bytes long.
 Data: <%Y-%m-%dT%H:%M:%> 25 59 2D 25 6D 2D 25 64 54 25 48 3A 25 4D 3A 25 
{172} normal block at 0x012D87A8, 8 bytes long.
 Data: <d       > 64 0E 89 0F 00 00 00 00 
{171} normal block at 0x012D8AF0, 8 bytes long.
 Data: <L       > 4C 0B 89 0F 00 00 00 00 
Object dump complete.

我使用 Poco 作为 DLL。 Poco 的版本是 1.9.0 我还使用 Dr. Memory 来检测内存泄漏。这是泄漏运行的摘要:

ERRORS FOUND:
              12 unique,    12 total unaddressable access(es)
               0 unique,     0 total uninitialized access(es)
             146 unique,   201 total invalid heap argument(s)
               0 unique,     0 total GDI usage error(s)
               0 unique,     0 total handle leak(s)
               0 unique,     0 total warning(s)
               0 unique,     0 total,      0 byte(s) of leak(s)
               0 unique,     0 total,      0 byte(s) of possible leak(s)

【问题讨论】:

    标签: c++ visual-studio memory-leaks poco-libraries


    【解决方案1】:

    首先值得注意的是,当您要求进行泄漏报告时,pDoc 仍然存在。所以你应该 1) 缩小pDoc 的范围 2) 停止使用 iostream 以避免可能创建警卫并再次检查。

    #define _CRTDBG_MAP_ALLOC  
    #include <stdlib.h>  
    #include <crtdbg.h>  
    #include <Poco/DOM/Document.h>
    #include <Poco/DOM/AutoPtr.h>
    int main()
    {
        {
            Poco::AutoPtr<Poco::XML::Document> pDoc = new Poco::XML::Document;
        }
        _CrtDumpMemoryLeaks();
        return 0;
    }
    

    另外,最好使用 VS 内存分析器而不是 _CrtDumpMemoryLeaks

    【讨论】:

    • 感谢您提供有关范围的提示,但输出仍然相同。它消除了内存泄漏
    • @Kevin“内存泄漏”在 C++ 代码中是完全正常的,许多库会静态分配内存,只有在应用程序终止时才会释放。需要注意的是,如果你运行你的代码两次,你会报告更多的内存泄漏吗?这些将是真正的泄漏,而不是静态分配。
    • @AlanBirtles 不,内存泄漏是错误,而不是“完全正常”。静态分配的内存是另一种野兽,它可能会使内存泄漏分析更加复杂,但严格来说它们不是“内存泄漏”(因为如果操作正确,就不会“泄漏”内存)
    • @roalz 我的意思是一些“内存泄漏”(如_CrtDumpMemoryLeaks 等简单工具所报告的)是完全正常的。我的其余评论解释了如何使用这些工具找到真正的内存泄漏
    • @AlanBirtles 如果您的意思是“您可能期望一些误报被 _CrtDumpMemoryLeaks 等脑死亡工具报告为内存泄漏”,那么我同意 ;-)
    【解决方案2】:

    已回复here

    这是检查泄漏的正确方法:

    int main()
    {
        _CrtMemState _state[3] = {0};
        _CrtMemCheckpoint(&_state[0]);
        {
            Poco::AutoPtr<Poco::XML::Document> pDoc = new Poco::XML::Document;
        }
        _CrtMemCheckpoint(&_state[1]);
        if (_CrtMemDifference(&_state[2], &_state[0], &_state[1]))
            _CrtMemDumpStatistics(&_state[2]); // Dump Memory Leaks
        return 0;
    }
    

    【讨论】:

    • 非常感谢 Alex 向我展示了这一点。如果我这样写,你是对的,一切都好 =) 它帮助我找到了我使用 Poco::XML 的类中的漏洞。
    猜你喜欢
    • 1970-01-01
    • 2011-02-18
    • 2020-04-11
    • 2011-03-27
    • 2015-12-27
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    相关资源
    最近更新 更多