Ok. Something I changed in my code recently is giving me a heap error when my ATL module tries to terminate.
ATL::AtlWinModuleTerm calls pWinModule->m_rgWindowClas
sAtoms.Rem
oveAll();
m_rgWindowClassAtoms is a CSimpleArray and remove all looks like this:
void RemoveAll()
{
if(m_aT != NULL)
{
for(int i = 0; i < m_nSize; i++)
m_aT[i].~T();
free(m_aT); // The Offending "free"
m_aT = NULL;
}
m_nSize = 0;
m_nAllocSize = 0;
}
Unfortunately, when it tries to free(m_aT), it asserts. The assert is from the following code:
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPo
inter(pUse
rData));
However, the offending window class (I've narrowed down the possibilities so I know exactly which class is causing the problem) is defined with CWindowImpl and uses the DECLARE_WND_CLASS macro.
CWindowImpl<CMyWindow,CWin
dow,CWinTr
aits<WS_DL
GFRAME | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0> >
DECLARE_WND_CLASS(_T("Joes
WindowClas
s"));
In short, I'm not managing rgWindowClassAtoms, ATL should be.
If I comment out the "free(m_aT)", the code works just fine. But I'm sure that's a memory leak for the rest of the CSimpleArrays out there. (Not sure if it matters for the Term(), but it probably does).
I'm using ATL 7.0 and the only clear insight I've found so far online is a write up that suggests both the underlying problem and a work-around.
http://discuss.develop.com/archives/wa.exe?A2=ind0202d&L=dotnet&D=1&T=0&F=&S=&P=72637
However, I /am/ statically linking to ATL as near as I can tell, so I should already have the workaround in place.
I'm really not sure what to do. For the moment I'm planning on re-writing the ATL files to avoid the bug, and accept the memory leak until I can figure out a way around this problem.
Anyone have a solution that isn't a memory leak?
-Joe
In ATL 7.0.,Init and Term methods have moved into the constructors and destructors for the module classes; there is no longer a need to call Init and Term.