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

C++调用COM DLL中可能出现的内存泄漏 我用VC++ 2017创建了一个C++控制台应用程序。它会随着时间的推移进行多次调用,以从第三方COM DLL检索数据。我使用像CComSafeArray和CComVariant这样的COM类来管理它们自己的释放,c++,visual-c++,memory-leaks,com,C++,Visual C++,Memory Leaks,Com,随着时间的推移,我观察到在每次COM调用之后,TaskManager中我的应用程序的内存稳步增加 我曾使用CRT库尝试检测内存泄漏,但它表明我没有内存泄漏 我的问题是: COM通常会像CRT那样进行自己的内存管理吗 库无法检测到但与我的进程关联? 如果是1,是否有工具可用于检测COM内存 泄漏? 如果是1,是否有方法对COM内存进行垃圾收集? 谢谢你的考虑 编辑日期:4-19-2019 我发现COM Dll返回函数调用结果的变量和BSTR。我将它们不同地分配到_variant_t和_bstr_t

随着时间的推移,我观察到在每次COM调用之后,TaskManager中我的应用程序的内存稳步增加

我曾使用CRT库尝试检测内存泄漏,但它表明我没有内存泄漏

我的问题是:

COM通常会像CRT那样进行自己的内存管理吗 库无法检测到但与我的进程关联? 如果是1,是否有工具可用于检测COM内存 泄漏? 如果是1,是否有方法对COM内存进行垃圾收集? 谢谢你的考虑

编辑日期:4-19-2019 我发现COM Dll返回函数调用结果的变量和BSTR。我将它们不同地分配到_variant_t和_bstr_t(如适用),以提供理论上的自动清理。 比如说

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

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

COM不使用任何自动垃圾收集;所有的事情都必须考虑到,尽管有一些助手类可以处理引用计数

COM中的约定是,如果被调用的方法分配了一些内存,那么调用方必须使用CoTaskMemFree释放它。您可能需要检查代码中调用的DLL方法,如果它们返回DLL分配的缓冲区中的任何内容,则需要调用CoTaskMemFree来释放该缓冲区

这里有更多详细信息:

\u bstr\u t b=GetSomeString

大概就是BSTR GetSomeString;。对于编译器来说,这意味着char\u t*GetSomeString;BSTR告诉您它使用COM语义,但编译器不知道这一点。这些语义是您调用SysFreeString的

_bstr\u t::\u bstr\u t wchar\u t*str copies str.是的,\u bstr\u t:~\u bstr\u t随后将调用SysFreeString,但它会在副本上这样做。您需要在BSTR GetSomeString;上调用SysFreeString

解决方案是:bool fCopy,fCopy=false。根据MSDN:

此构造函数由类型库中的包装函数使用 用于封装返回的BSTR并获取其所有权的标头 通过接口方法


有关变量,请参见_VARIANT::_VARIANT\u tVARIANT&varSrc,bool fCopy;。同样的想法。

通过任务管理器观察内存增加并不是判断内存增加的可靠方法。当您删除/删除[]/free/etc内存时,通常不会直接返回操作系统。考虑到答案,如果这是一个现代的应用程序,那么COM对象的严重泄漏不应该令人惊讶,因为MS大多通过先前在COM中使用的引用计数放弃了对象生命周期管理的弱概念。因此,与跟踪COM内存泄漏不同,您可能应该专注于使应用程序在因资源耗尽而被终止后正确重新启动。@VTT:如果我可以对注释进行向下投票,我将进行向下投票。我修改了我的问题编辑注释,以提供有关COM dll返回的内容以及如何分配返回值的一些见解。我愿意接受这个答案是因为它有道理。然而,我发现这个COM dll在没有从中提取任何数据的情况下泄漏了严重的内存。它打开和关闭文件系统文件,但似乎无法自行清理。所以我不能肯定这个答案能解决我的问题。然而,我确实采纳了这些建议。