C++ 在 COM DLL 中调用函数可能的内存泄漏

C++ Calling Functions in a COM DLL Possible Memory Leak

我使用 VC++ 2017 创建了一个 C++ 控制台应用程序。随着时间的推移,它会进行多次调用以从第 3 方 COM DLL 检索数据。我使用像 CComSafeArray 和 CComVariant 这样的 COM 类 来管理它们自己的释放。

随着时间的推移,我观察到每次 COM 调用后我的应用程序的内存在任务管理器中稳定增加。

我已经使用 CRT 库 (https://docs.microsoft.com/en-us/visualstudio/debugger/finding-memory-leaks-using-the-crt-library?view=vs-2019) 尝试检测内存泄漏,但它表明我有 none。

我的问题is/are:

  1. COM 是否通常进行 CRT 自己的内存管理 库无法检测到但与我的进程相关联?
  2. 如果#1 是这种情况,是否有可用的工具来检测 COM 内存 泄漏?
  3. 如果#1 是这种情况,是否有垃圾收集 COM 内存的方法?

感谢您的考虑。

编辑 2019 年 4 月 19 日 我发现函数调用结果的 COM Dll returns VARIANT 和 BSTR。我将它们分配给 _variant_t 和 _bstr_t 以提供自动清理(理论上)。 例如。

_variant_t v = GetSomeVariant();
_bstr_t b = GetSomeString();

DLL 不使用 CoTaskMemAlloc,但它确实使用 SysAllocString 来生成 BSTR。

COM 不使用任何自动垃圾收集;尽管有帮助程序 类 可用于处理引用计数,但所有内容都必须考虑在内。

COM 中的惯例是,如果被调用的方法分配了一些内存,那么调用者必须使用 CoTaskMemFree 释放它。您可能想检查您调用的 DLL 方法的代码,如果它们 return 由 DLL 分配的缓冲区中的任何内容,那么您需要通过调用 CoTaskMemFree.[ 来释放该缓冲区。 =14=]

https://docs.microsoft.com/en-us/windows/desktop/learnwin32/memory-allocation-in-com

此处有更多详细信息:https://docs.microsoft.com/en-us/windows/desktop/com/memory-management-rules

_bstr_t b = GetSomeString();

据推测,也就是BSTR GetSomeString();。这对编译器意味着 wchar_t* GetSomeStringBSTR 告诉您它使用 COM 语义,但编译器不知道。这些语义就是你所说的SysFreeString

_bstr_t::_bstr_t( wchar_t* str )str。是的,_bstr_t::~_bstr_t 然后会调用 SysFreeString,但它是在副本上调用的。您需要在 BSTR GetSomeString(); 上调用 SysFreeString

解决方案是 _bstr_t::_bstr_t( BSTR bstr , bool fCopy )fCopy=false。根据 MSDN:

This constructor is used by wrapper functions in the type library headers to encapsulate and take ownership of a BSTR that is returned by an interface method.

对于 VARIANT,参见 _variant_t::_variant_t(VARIANT& varSrc, bool fCopy);。同样的想法。