【问题标题】:MemoryLeak or false positive of DeLeaker when returning BSTR返回 BSTR 时 DeLeaker 的 MemoryLeak 或误报
【发布时间】:2020-11-24 13:52:39
【问题描述】:

我有返回 BSTR 的 COM 函数。并像这样使用:

界面:

interface ITexts : IDispatch
{
    [id(5)] HRESULT GetText([in] long Number, [in] long LangID, [out,retval] BSTR* pText);
};

实现

STDMETHODIMP CTexts::GetText(long Number, long LangID, BSTR *pText)
{
    CString sDummyValue = _T("gettext"); //just for testing
    sDummyValue.SetSysString(pText);
    return S_OK;
}

还有客户

CString RITexts::GetText(long Number, long LangID)
{
    CString result;
    static BYTE parms[] = VTS_I4 VTS_I4;
    InvokeHelper(0x5, DISPATCH_METHOD, VT_BSTR, (void*)&result, parms, Number, LangID);
    return result;
}

当作为调试构建运行时,Visual Studio 不会抱怨,但 DeLeaker(内存泄漏监控工具)认为存在内存泄漏:

OLEAUT32.dll!SysReAllocStringLen 76543120
mfc140ud.dll!ATL::ChTraitsCRT<wchar_t>::ReAllocSysString Line 815 + 0xe bytes 7a2d0012
mfc140ud.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >::SetSysString Line 2288 + 0x16 bytes 7a2d0a39
(-> ComClass) LangSupp.dll!CTexts::GetText Line 343 + 0x9 bytes 7b1698b2
OLEAUT32.dll!DispCallFunc + 0x16d bytes 7655840d
OLEAUT32.dll!CTypeInfo2::Invoke + 0x2e6 bytes 7653aca6
LangSupp.dll!ATL::CComTypeInfoHolder::Invoke Line 4204 + 0x31 bytes 7b15c056
LangSupp.dll!ATL::IDispatchImpl<ITexts,&IID_ITexts,&LIBID_LANGSUPPLib,1,0,ATL::CComTypeInfoHolder>::Invoke Line 5163 + 0x2a bytes 7b15bfa2
mfc140ud.dll!COleDispatchDriver::InvokeHelperV Line 399 + 0x7 bytes 7a1e6d6b
mfc140ud.dll!COleDispatchDriver::InvokeHelper Line 554 + 0x1d bytes 7a1e6597
(-> Client) Managers.dll!RITexts::GetText Line 104 + 0x1b bytes 7ac2ce3a 

那么这是来自 DeLeaker 的误报还是我错过了释放字符串的一些内容?

【问题讨论】:

    标签: visual-c++ memory-leaks com bstr


    【解决方案1】:

    调用InvokeHelper不正确。

    result 的类型应该是BSTR,或者更好地使用像_bstr_tCComBSTR 这样的包装器来确保为BSTR 分配的内存将被释放。

    【讨论】:

    • Ì 添加了一条评论,但它不见了? InvokeHelper 是由 VisualStudio 生成的,所以我怀疑是这个问题
    • @suriel 问题是谁将调用 SysFreeString。 CString 的析构函数没有。
    【解决方案2】:

    服务器正确,客户端错误。您想使用变体类型从自动调用中获取结果。试试:

    CString RITexts::GetText(long Number, long LangID)
    {
        static BYTE parms[] = VTS_I4 VTS_I4;
        _variant_t vResult;
        InvokeHelper(0x5, DISPATCH_METHOD, VT_VARIANT, (void*)&vResult, parms, Number, LangID);
        CString result((wchar_t*) vResult.bstrVal); // should have error checking of your result and type
        return result;
    }
    

    【讨论】:

    • 非常感谢。我只是不知道为什么 VS 多年来一直在生成这样的代码,而且我看不到它有任何影响。在这里发布了关于他的另一个问题:stackoverflow.com/questions/63378035/…
    猜你喜欢
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    相关资源
    最近更新 更多