2009-11-16 5 views
4

Каковы наиболее часто встречающиеся причины утечки памяти COM?Каковы часто встречающиеся причины утечек памяти COM?

Я прочитал, что передача адреса инициализированного CComBSTR функции в качестве параметра [out] вызывает утечку. Я хочу перечислить другие распространенные ошибки программирования, подобные этому.

ответ

4

Забыв позвонить Release(), когда вам нужно. Используйте CComPtr <>, CComVARIANT <> и CComBSTR, чтобы помочь вам.

7

Невозможно использовать типы обертки RAII для COM-объектов. В частности, не используется CComPtr<>, CComBSTR и CComVARIANT<>. Эти объекты help предотвращают утечку, удаляя ответственность за освобождение базового ресурса от разработчика. Объект wrapper принудительно освобождает ресурсы в своем деструкторе.

Другая причина утечек или случайных ошибок, которые я видел, является результатом неявного преобразования от CComPtr<T> до T*. Это полезно для передачи обернутых объектов в качестве аргументов. Но это может вызвать проблемы, потому что это допускает неявное преобразование между объектом RAII и необработанным указателем. Например

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

Вызов SomeCall, скорее всего, не в состоянии в этом случае, так как объект pFoo умер в этой точке. Зачем? Значение было возвращено с помощью ref count 1 из GetAFoo, назначенного pFoo, а затем уменьшилось до 0 и удалено, поскольку временное значение выпало из области видимости.

2

Существует две основные причины: использование RAII (интеллектуальных указателей) и неправильное использование RAII.

Если вы используете необработанные указатели - IInterface * или BSTR, вы рискуете забыть вызвать IInterface :: Release() или SysFreeString(), и это вызовет утечку. Если вы неправильно используете интеллектуальные указатели, вы также рискуете утечками памяти. Один из способов сделать это - тот, который вы упомянули, - передать инициализированный оператор CComBSTR :: &() в качестве параметра [out]. Существуют и другие способы, такие как передача CComPtr :: operator &() или CCOmQIPtr :: operator &() инициализированного интеллектуального указателя в качестве параметра [out] с отключенными ATLASSERT. Или создавая любую подобную графу структуру с циклом и полностью освобождая ее, чтобы объект в цикле удерживал интеллектуальные указатели друг к другу и предотвращал освобождение.

Смежные вопросы