FIX: Calling delete or free() in ATL Causes Access Violation

This article was previously published under Q190531
This article has been archived. It is offered "as is" and will no longer be updated.
When you call the delete operator or free() function in an ATL project, it might cause an access violation if you are running on a multi-processor computer.
ATL provides an implementation of free() in non-debug builds with_ATL_MIN_CRT defined. The delete operator is also overridden to callfree(). On multi-processor computers, the pointer passed in to free() isused to calculate an offset to the heap's handle:
void __cdecl free(void* p){#ifndef _ATL_NO_MP_HEAP   if (_Module.m_phHeaps == NULL)#endif      HeapFree(_Module.m_hHeap, 0, p);#ifndef _ATL_NO_MP_HEAP   else   {      HANDLE* pHeap = ((HANDLE*)p)-nOffsetBlock;      HeapFree(*pHeap, 0, pHeap);   }#endif}				
There is no code here that checks if "p" is NULL; therefore, so HeapFree()is called with an invalid handle.
The implementation of free() needs to be modified in Atlimpl.cpp. Oneoption to resolve this problem is to just return if the pointer is NULL:
   void __cdecl free(void* p)   {      if (p == NULL)  // Add this line.         return;      // Add this line.   #ifndef _ATL_NO_MP_HEAP      if (_Module.m_phHeaps == NULL)   #endif         HeapFree(_Module.m_hHeap, 0, p);   #ifndef _ATL_NO_MP_HEAP      else      {         HANDLE* pHeap = ((HANDLE*)p)-nOffsetBlock;         HeapFree(*pHeap, 0, pHeap);      }   #endif   }				
Another option to resolve this problem is to #define _ATL_NO_MP_HEAP. Thisprevents the problematic code from being included. However, this does turnoff the optimization that ATL adds for multi-processor machines. You haveonly one heap regardless of the number of processors. Heap access may beless than optimal because access from multiple threads is serialized.
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article. This bug was corrected in Visual Studio 6.0 Service Pack 3. For more information about Visual Studio service packs, please see the following articles in the Microsoft Knowledge Base:

194022 INFO: Visual Studio 6.0 Service Packs, What, Where, Why

194295 HOWTO: Tell That Visual Studio 6.0 Service Packs Are Installed
This bug occurs only under all of the following conditions:
  • You are running on a multi-processor computer.
  • The pointer passed to delete or free() is NULL.
  • _ATL_MIN_CRT is defined (default).
  • You are building for release (_DEBUG is not defined).
  • _ATL_NO_MP_HEAP is not defined (default).
unhandled exception new malloc memory

Article ID: 190531 - Last Review: 01/09/2015 12:36:30 - Revision: 4.0

  • Microsoft ActiveX Template Library 3.0
  • kbnosurvey kbarchive kbbug kbfix kbcrt kbvs600sp3fix KB190531