| FIX: Temporary Object Memory Leak in Foundation ClassesID: Q98867 
 | 
Under some circumstances, an application created with Microsoft Foundation Classes version 2.0 allocates temporary objects on the application heap and does not delete them. While the memory diagnostics in the debugging version of the Foundation Classes libraries do not detect this memory leak, the error is apparent when Heap Walker is used to monitor the heap.
A HANDLE is attached to both a permanent object and a temporary object. When the HANDLE is detached from the permanent object, it is also detached from the temporary object. Consequently, the temporary object is never destroyed.
Do not remove the HANDLE from the temporary map when it is detached. To do so, remove one line of code from the WINHAND.CPP source file. In Visual C++, remove line 158 which reads as follows:
   m_temporaryMap.RemoveKey((MAPTYPE)h); 
   ASSERT(ph[0] == h); 
   ASSERT(ph[0] == h || ph[0] == NULL); Microsoft has confirmed this to be a problem in the Microsoft Foundation Class Libraries version 2.0 for Windows. This problem was corrected in the MFC libraries version 2.5, which ships with Microsoft VC++ version 1.5.
The Foundation Class Libraries maintain two maps for each HANDLE used
in the Microsoft Windows environment. The Libraries maintain four map
pairs, for HDCs, HGDIOBJECTs, HMENUs, and HWNDs. For each handle type,
the Libraries maintain two separate maps: a temporary map and a
permanent map. When the Library maps a HANDLE to a C++ object, it
checks the permanent map first and then checks the temporary map.
Under some circumstances, a HANDLE appears in both maps. A serious
memory leak occurs when a HANDLE is Detached (or unmapped) from its
permanent C++ object. This removes the HANDLE from both maps even
though the temporary object is not destroyed. Because the temporary
C++ object is not present in the temporary map when the
CWinApp::OnIdle() function attempts to delete all temporary objects,
the temporary C++ object remains in memory. For example, the following
code example causes a memory leak that involves one temporary CDC
object:
   CDC* pDC = CDC::FromHandle(hDC); // creates temporary object
   CDC dc;
   dc.Attach(hDC); // now in permanent map as well
   dc.Detach(hDC); // removed from temp and permanent map
   // pDC is never deleted Additional query words:
Keywords          : kb16bitonly kbnokeyword kbMFC kbVC 
Version           : 1.0
Platform          : WINDOWS 
Issue type        : kbbug Last Reviewed: August 8, 1999