C++泄漏VARIANT/bstrVal代码

use*_*027 6 c++ com memory-leaks bstr variant

泄漏检查程序告诉我内存中有内存泄漏,在以下代码中分配:

// Get the value from the object as a variant.
VARIANT vVal;
VariantInit ( &vVal );
hres = clsObj->Get ( fieldName.c_str(), 0, &vVal, 0, 0 );
if ( FAILED ( hres ) )
{
    (... various cleanup / throw stuff ...)
}

// And get it as a wstring.
wstring val ( vVal.bstrVal );

(... do some standard, non-memory leaking stuff with the wstring ...)    

// Clean up.
VariantClear ( &vVal );
Run Code Online (Sandbox Code Playgroud)

其中的"clsObj"是一个IWbemClassObject,它是WMI东西的Microsoft接口.

分配泄漏内存的特定行是"clsObj-> Get"行.然后泄漏检查器报告泄漏本身的更具体的代码(即,在分配泄漏的内存时的堆栈跟踪中),我没有源代码:

(ole32): (filename not available): CoRevokeMallocSpy    
(OLEAUT32): (filename not available): GetErrorInfo  
(OLEAUT32): (filename not available): SysAllocStringLen 
(OLEAUT32): (filename not available): SysAllocString    
(wbemcomn): (filename not available): CVar::SetBSTR 
(wbemcomn): (filename not available): CVar::FillVariant 
(fastprox): (filename not available): CWbemObject::Get  
Run Code Online (Sandbox Code Playgroud)

因此,看起来VARIANT vVal中的潜在BSTR正在泄露.但我正在做一个VariantClear ......我还要做别的吗?

也许我在wstring构造函数中泄漏它?但如果是这样,我不明白.我认为bstrVal基本上只归结为char指针(或wchar或其他); wstring构造函数应该只是从该地址复制,就像它是任何其他指针一样,对吧?

它不像wstring构造函数接管清理vVal.bstrVal最初指向的内存的责任,就像它在一些引用计数的COM对象上执行Detach()一样,是吗?

如果它很重要,这是在Visual C++ 6中.

Sta*_*lot 0

ABSTR是两个数据元素。它是一个int具有基本字符串长度计数和基本字符串的计数。因此,即使您有一个空的BSTRHolding "",您也必须在BSTR为其分配新值之前正确清空它。否则,即使释放“字符串”部分,也会泄漏int数据成员。

我怀疑您泄漏了 fieldname.c_str()。它可能正在BSTR堆栈上创建一个并且正在泄漏。

更改您的代码来执行此操作:

CComBSTR tempBSTR = fieldName.c_str();
hres = clsObj->Get ( tempBSTR, 0, &vVal, 0, 0 );
Run Code Online (Sandbox Code Playgroud)

这至少可以让您确保它不是自动构建的,BSTR在您调用 Get() 时会泄漏。

顺便说一句,如果您必须使用BSTR,请考虑使用 usingCComBSTR代替它。它可以帮助防止基本的内存泄漏。