Visual Studio 2017 使用 Poco 检测内存泄漏 Xml 文档

Visual Studio 2017 detect memory Leak when using Poco Xml Document

如果我使用 Poco::XML::Document Class,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里面的Leak Dump(我省略了一些部分,因为它真的很大):

{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)

首先值得注意的是,当您要求泄漏报告时,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

已回答 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;
}