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.h,m_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。
我是 运行 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.h,m_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。