COM内存泄漏的常见原因是什么?

时间:2009-11-16 17:22:28

标签: com memory-leaks

COM内存泄漏最常见的原因是什么?

我已经读过将初始化的CComBSTR的地址作为[out]参数传递给函数会导致泄漏。我想列举其他常见的编程错误。

3 个答案:

答案 0 :(得分:7)

未能为COM对象使用RAII包装类型。特别是不使用CComPtr<>CComBSTRCComVARIANT<>。这些对象 help 通过消除从开发人员释放底层资源的责任来防止泄漏。包装对象强制在其析构函数中释放资源。

我看到的泄漏或意外释放的另一个原因是从CComPtr<T>T*的隐式转换。这对于将包装对象作为参数传递很有用。但它可能会导致问题,因为它允许RAII对象和原始指针之间的隐式转换。例如

CComPtr<IFoo> GetAFoo();  // Imagine if this creates the object
...
IFoo* pFoo = GetAFoo();   
pFoo->SomeCall();  

在这种情况下,对SomeCall的调用可能会失败,因为此时对象pFoo已经死了。为什么?返回值为GetAFoo的ref计数为1,分配给pFoo,然后递减为0并删除,因为临时值超出范围。

答案 1 :(得分:4)

忘记在应该的时候调用Release()。使用CComPtr&lt;&gt;,CComVARIANT&lt;&gt;和CComBSTR来帮助你。

答案 2 :(得分:2)

主要有两个原因:不使用RAII(智能指针)和滥用RAII。

如果您使用原始指针--Interface *或BSTR,您可能会忘记调用IInterface :: Release()或SysFreeString(),这将导致泄漏。如果您错误地使用智能指针,也会导致内存泄漏。一种方法是你提到的那个 - 将初始化的CComBSTR :: operator&amp;()作为[out]参数传递。还有其他方法,例如将初始化智能指针的CComPtr :: operator&amp;()或CCOmQIPtr :: operator&amp;()作为[out]参数传递,禁用ATLASSERT。或者使用循环创建任何类似图形的结构并完全释放它,以便循环中的对象每个都保持智能指针并防止释放。