atldbsch.h 中的 BSTR 内存泄漏 - 怎么办?

BSTR memory leak in atldbsch.h - what to do?

我是 运行 Deleaker 应用程序,用于查找和修复应用程序中的内存泄漏。 现在,它在 Microsoft CRestrictions class(atldbsch.h 文件)的 Open() 函数中发现了很多 BSTR 漏洞。

如果仔细观察,就会注意到它需要 7 个 LPCTSTR 参数,然后像这样使用它们:

pVariant = m_pvarRestrictions + 1;
.
.
pVariant->bstrVal = ::SysAllocString(T2COLE_EX_DEF(lpszParam1));

对所有七个这样的参数都这样做(每次增加数字 1)。

析构函数只是在做

delete[] m_pvarRestrictions;

但是通过 ::SysAllocString() 分配的 BSTR 永远不会通过调用 ::SysFreeStr() 释放

我是不是遗漏了什么或者有泄漏,在这种情况下应该如何处理?

根据 https://github.com/dpalma/sge/blob/master/3rdparty/atl/atldbsch.hm_pvarRestrictions 定义为 ATL::CComVariant *,因此 ATL::CComVariant 析构函数应该清理 BSTR 变体(代码是将 vt 正确设置为 VT_BSTR)。也就是说,CComVariant 析构函数调用 CComVariant::Clear,后者调用 VariantClear.

因此,这里不应该有内存泄漏 -- 代码看起来是正确的。这可能是 Deleaker 检测到此模式时出现问题。

您确定将 pVariant 类型也设置为 VT_BSTR 吗?这没有在代码中显示。如果你不设置类型,这将导致泄漏。

如果 pVariant 实际上是指向 CComVariant 的指针,则此代码应该有效:

*pVariant = T2COLE_EX_DEF(lpszParam1);

并且在这种情况下 VT_BSTR 类型被设置并且销毁将清除变体。

检查代码后我会说这里没有泄漏,因为 m_pvarRestrictions 是指向 CComVariant 数组的指针,并且该数组是通过 delete[] 删除的,因此调用了每个 CComVariant 的析构函数。 CComVariant::~CComVariant() 调用 VariantClear,如果此 VARIANT 包含它,它本身会释放 BSTR。

然后我检查了 Deleaker(版本 3.0.66.0)如何与 CComVariant 一起工作,这里是我的代码:

int _tmain(int argc, _TCHAR* argv[])
{
    CComVariant* v = new CComVariant(L"123");
    delete v;

    return 0;
}

没有显示泄漏。可能您已经尝试过旧版本的 Deleaker。

如果我删除 delete v,则会看到两个泄漏:堆内存和 BSTR。