【问题标题】:What are the frequently-encountered causes for COM memory leaks?COM 内存泄漏的常见原因有哪些?
【发布时间】:2017-08-12 01:31:36
【问题描述】:

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

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

【问题讨论】:

    标签: com memory-leaks


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

      在应该调用 Release() 时忘记了。使用 CComPtr、CComVARIANT 和 CComBSTR 来帮助您。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-11
          • 1970-01-01
          • 2012-05-06
          • 1970-01-01
          • 1970-01-01
          • 2010-09-22
          • 2023-03-08
          • 1970-01-01
          相关资源
          最近更新 更多