我必须处理使用MSXML将测量数据写入简单XML文件的遗留应用程序。基本上,这就是发生的事情:
MSXML2::IXMLDOMDocument2Ptr pXmlDocument;
HRESULT comResult = CXMLUtil::createXMLDocument(pXmlDocument);
// ... check HRESULT ...
MSXML2::IXMLDOMNodePtr pXmlMainNode = pXmlDocument.GetInterfacePtr();
MSXML2::IXMLDOMNodePtr pXmlSubNode = CXMLUtil::AppendNewElement(pXmlDocument, pXmlMainNode, RootTag, "");
// ... create further nodes ...
MSXML2::IXMLDOMNodePtr pXmlTmpNode = CXMLUtil::AppendNewElement(
pXmlDocument,
pXmlDataSetNode,
measDataTag,
measdata,
numberOfDataItems );
// ... append further items ...
在每个项目之后,调用pXmlTmpNode.Release()
。最后,所有其他节点以及pXmlDocument
都是Released
。
createXMLDocument
定义如下:
HRESULT CXMLUtil::createXMLDocument(MSXML2::IXMLDOMDocument2Ptr &pXmlDocument) {
MSXML2::IXMLDOMDocument2 *xmlDocument = 0;
HRESULT comError = CoCreateInstance(__uuidof(MSXML2::DOMDocument),NULL,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&xmlDocument));
if (comError) return comError;
xmlDocument->put_async(VARIANT_FALSE);
xmlDocument->put_validateOnParse(VARIANT_FALSE);
xmlDocument->put_resolveExternals(VARIANT_FALSE);
xmlDocument->put_preserveWhiteSpace(VARIANT_TRUE);
MSXML2::IXMLDOMDocument2Ptr ptr(xmlDocument);
pXmlDocument = ptr;
return comError;
}
为了追加新元素(即unsiged char
数组),应用此函数:
MSXML2::IXMLDOMNodePtr CXMLUtil::AppendNewElement(MSXML2::IXMLDOMDocument2Ptr pXMLDom, MSXML2::IXMLDOMNodePtr pParent, CComBSTR strElementName, unsigned char* pData, long nData) {
MSXML2::IXMLDOMNodePtr pData1 = pXMLDom->createElement(BSTR(strElementName));
pData1->put_dataType(CComBSTR(_T("bin.base64")));
SAFEARRAY* psa = SafeArrayCreateVector( VT_UI1, 0L, nData);
psa->pvData = pData;
VARIANT var;
VariantInit(&var);
var.parray = psa;
var.vt = (VT_ARRAY | VT_UI1 );
pData1->nodeTypedValue = var;
pParent->appendChild(pData1);
SafeArrayDestroy(psa);
return pData1;
}
无论使用何种#import <msxml4.dll>
或#import <msxml6.dll>
,都会出现内存泄漏。由于measdata
等可能很大,这是一个非常大的问题。我可以做些什么来使代码工作?
谢谢,马修
答案 0 :(得分:2)
MSXML2::IXMLDOMDocument2 *xmlDocument = 0;
HRESULT comError = CoCreateInstance(__uuidof(MSXML2::DOMDocument),
NULL,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&xmlDocument));
...
MSXML2::IXMLDOMDocument2Ptr ptr(xmlDocument);
pXmlDocument = ptr;
此代码泄漏xmlDocument
。 ptr(xmlDocument)
执行了额外的AddRef
,但xmlDocument没有Release
超出范围。你在任何地方都使用智能ptrs,没有理由不在这里使用它,也许是这样的:
MSXML2::IXMLDOMDocument2Ptr xmlDocument;
HRESULT comError = CoCreateInstance(__uuidof(MSXML2::DOMDocument),
NULL,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&xmlDocument));
...
pXmlDocument = xmlDocument;