Suspected memory leak in ATLCOM.h in CComCreator::CreateInstance
(I apologize if this gets double-posted. I tried to post this once, but it
seemed to fail. I cannot afford to wait to see if it shows up as I am under a
deadline
If there are two, please leave this one and delete the other one - feel free
to delete this comment if you are able).
I am running Visual Studio 8.
I'm maintaining some legacy code, and I found what I believe to be a memory
leak leaving scope in the ATL code.
We define the following COM object. I left out much of the code. - I can
post more if the details matter, but I suspect that if you read to the end of
this message, you'll see the memory leak is inevitable.
class ATL_NO_VTABLE MyCOMClass :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CSomeType, &CLSID_SomeType>,
public IDispatchImpl<ISomeType, &IID_ISomeType, &LIBID_OurLib, /*wMajor
=*/ 2, /*wMinor =*/ 0>,
public ISupportErrorInfo
{
// Rest of class definition omitted for brevity - I can post more if
necessary.
}
Later in another method, we call MyCOMClass::CreateInstance as shown. This
is called over and over again thousands of times during a session, and memory
is leaked each time, even after Release the COM object instances. Again, see
further below for the exact location of the leaked memory.
HRESULT hr = MyCOMClass::CreateInstance( NULL, (ISomeType**)&pWrapper );
This goes through the following calls (an inverted stack trace, the last
call shown is the final destination).
CComCoClass<class CMyCOMClass,&struct _GUID const
CLSID_MyCOMClass>::CreateInstance<struct IMyCOMClass> atlcom.h 3565
CComCreator2<class ATL::CComCreator<class ATL::CComObject<class
CMyCOMClass> >,class ATL::CComCreator<class ATL::CComAggObject<class
CMyCOMClass> > >::CreateInstance atlcom.h 1873
CComCreator<class ATL::CComObject<class CMyCOMClass> >::CreateInstance
atlcom.h 1792
Finally, we arrive at the CreateInstance method shown below.
Note, in the code below, if QueryInterface succeeds, nothing frees the
memory pointed to by automatic variable 'p'.
template <class T1>
class CComCreator
{
public:
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv)
{
ATLASSERT(ppv != NULL);
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
HRESULT hRes = E_OUTOFMEMORY;
T1* p = NULL;
#pragma warning(push)
#pragma warning(disable: 6014)
/* prefast noise VSW 489981 */
ATLTRY(p = new T1(pv)) // ********** THIS IS LEAKED **********
#pragma warning(pop)
if (p != NULL)
{
p->SetVoid(pv);
p->InternalFinalConstructAddRef();
hRes = p->_AtlInitialConstruct();
if (SUCCEEDED(hRes))
hRes = p->FinalConstruct();
if (SUCCEEDED(hRes))
hRes = p->_AtlFinalConstruct();
p->InternalFinalConstructRelease();
if (hRes == S_OK)
hRes = p->QueryInterface(riid, ppv);
if (hRes != S_OK)
delete p;
}
return hRes;
}
};
How can this work?
Do we need to use CoCreateInstance to avoid this leak?
Thanks in advance.
--
You're unique, just like everyone else.