2009-11-16 3 views

답변

4

필요한 경우 Release()를 호출하는 것을 잊어 버렸습니다. CComPtr <>, CComVARIANT <> 및 CComBSTR을 사용하면 도움이됩니다.

7

COM 개체에 RAII 래퍼 유형을 사용하지 못합니다. 특히 CComPtr<>, CComBSTRCComVARIANT<>을 사용하지 않는 것이 좋습니다. 이 객체들 도움은 개발자로부터 기본 리소스를 해제하는 책임을 제거하여 누출을 방지합니다. 랩핑 객체는 소멸자의 자원 해제를 강제합니다.

내가 본 적이있는 또 다른 원인은 CComPtr<T>에서 T*으로 암시 적으로 변환 된 결과입니다. 래핑 된 객체를 인수로 전달할 때 유용합니다. 그러나 RAII 오브젝트와 원시 포인터 사이의 암시 적 변환을 허용하기 때문에 문제가 발생할 수 있습니다. 객체 pFoo이 시점에서 죽었 때문에 예를

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

를 들어 SomeCall에 대한 호출은 가능성이 시나리오에서 실패합니다. 왜? 이 값은 GetAFoo에서 ref 카운트 1로 반환되고 pFoo에 할당 된 다음 0으로 감소되고 임시 값이 범위를 벗어 났으므로 삭제됩니다.

2

RAII (스마트 포인터)를 사용하지 않고 RAII를 잘못 사용하는 데는 두 가지 주된 이유가 있습니다.

원시 포인터 - IInterface * 또는 BSTR을 사용하는 경우 IInterface :: Release() 또는 SysFreeString()을 호출하는 것을 잊어 버릴 위험이 있으며 이로 인해 누출이 발생할 수 있습니다. 스마트 포인터를 잘못 사용하면 메모리 누수가 발생할 위험이 있습니다. 이를 수행하는 한 가지 방법은 초기화 된 CComBSTR :: operator &()을 [out] 매개 변수로 전달하는 것입니다. CComPtr :: operator &() 또는 초기화 된 스마트 포인터의 CCOmQIPtr :: operator &()을 ATLASSERT가 비활성화 된 상태로 [out] 매개 변수로 전달하는 등의 다른 방법이 있습니다. 또는 루프를 사용하여 그래프와 같은 구조를 생성하고 루프 내의 객체가 서로 스마트 포인터를 유지하고 해제하지 못하도록 완전히 해제합니다.