使用 MSXML 和智能指针的代码中的内存泄漏

Memory leak in code using MSXML and smart pointers

提问人:codesniffer 提问时间:9/6/2023 最后编辑:codesniffer 更新时间:9/7/2023 访问量:29

问:

以下代码中的某些内容正在泄漏内存,但我找不到它。

我已经使用调试器对其进行了跟踪,即使使用调试版本,它也不会进入 ref 计数。所以我种了成对的.AddRef() 和 .Release() 查看所有指针在不同点的引用计数。对我来说最突出的是 ref 计数为 2 的结果。如果我尝试用 .Release(),则应用稍后会在代码中触发断言。createProcessingInstruction

下面代码中的外大括号是我代码的一部分,因此其中的所有智能指针都应该在末尾释放。 比这一部分更长寿,并被确定不是泄漏的一部分。parser

当我在循环中运行此代码时,提交大小(当然还有峰值提交大小)在所有任务管理器、进程资源管理器中稳步增长,并通过 .GetProcessMemoryInfo

MSXML2::IXMLDOMDocument3Ptr parser;
HRESULT hr(parser.CreateInstance(__uuidof(MSXML2::DOMDocument60) ) );
if(FAILED(hr) )
{
    throw(XmlException("Failed to create instance of MSXML."));
}
parser->preserveWhiteSpace = VARIANT_TRUE;

...
// Various methods to populate the XML.  Omitted because this was determined to not leak
...

// Something within this section is leaking.
{
    const std::wstring wstrXmlDeclaration(L" version=\"1.0\" encoding=\"UTF-16\"");
    // TODO:  If this is expensive, maybe store an instance?
    IXMLDOMProcessingInstructionPtr pProcessingInstruction(
        parser->createProcessingInstruction(
            L"xml",
            wstrXmlDeclaration.c_str()
        )
    );
    if(!pProcessingInstruction)
    {
        throw(XmlException("Failed to create instruction for encoding.") );
    }
    DWORD ulRefCount = pProcessingInstruction->AddRef();
    ulRefCount = pProcessingInstruction->Release();

    // NOTE: ulRefCount is 2 here (??)

    MSXML2::IXMLDOMNodePtr pFirstChild(
        parser->GetfirstChild()
    );
    if(!pFirstChild)
    {
        throw(XmlException("Failed to get XML Declaration of XML Document.") );
    }

    const std::wstring wstrFirstChildName(pFirstChild->nodeName);
    assert(wstrFirstChildName == L"xml");
    if(wstrFirstChildName != L"xml")
    {
        throw(XmlException("Unexpected first element (XML Declaration) in XML."));
    }

    MSXML2::IXMLDOMNodePtr pOldChild(
        parser->replaceChild(
            static_cast<MSXML2::IXMLDOMNode*>(pProcessingNode),
            static_cast<MSXML2::IXMLDOMNode*>(pFirstChild)
        )
    );
    if(!pOldChild)
    {
        throw(XmlException("Failed to apply specified encoding.") );
    }
}
内存泄漏 msxml msxml6

评论

1赞 Artem Razin 9/6/2023
很高兴看到一个可以采取和建立的样本。否则,很难说代码出了什么问题。但我可以建议在循环中运行有问题的代码,然后使用像 Deleaker 这样的内存分析器对其进行分析。
1赞 codesniffer 9/7/2023
谢谢@ArtemRazin我已经在研究这两个建议,以及尝试消除过程。

答: 暂无答案