C6250

warning C6250: Calling <function> VirtualFree without the MEM_RELEASE flag may free memory but not address descriptors (VADs); results in address space leaks

This warning indicates that a call to VirtualFree without the MEM_RELEASE flag only decommits the pages, and does not release them. To decommit and release pages, use MEM_RELEASE flag in call to VirtualFree. If any pages in the region are committed, the function first decommits and then releases them. After this operation, the pages are in the free state. If you specify this flag, dwSize must be zero, and lpAddress must point to the base address returned by the VirtualAlloc function when the region was reserved. The function fails if either of these conditions is not met.

You can ignore this warning if your code later frees the address space by calling VirtualFree with the MEM_RELEASE flag.

For more information see VirtualAlloc and VirtualFree.

The use of VirtualAlloc and VirtualFree have many pitfalls in terms of memory leaks and exceptions. To avoid these kinds of leaks and exception problems altogether, use the mechanisms that are provided by the C++ Standard Template Library (STL). These include shared_ptr, unique_ptr, and vector. For more information, see Smart Pointers (Modern C++) and Standard C++ Library Reference.

Example

The following sample code generates this warning:

#include <windows.h>
#include <stdio.h>
#define PAGELIMIT 80            

DWORD dwPages = 0;  // count of pages 
DWORD dwPageSize;   // page size 

VOID f( )
{
  LPVOID lpvBase;            // base address of the test memory
  SYSTEM_INFO sSysInfo;      // system information

  GetSystemInfo(&sSysInfo);  
  dwPageSize = sSysInfo.dwPageSize;

  // Reserve pages in the process's virtual address space
  lpvBase = VirtualAlloc(
                         NULL,                // system selects address
                         PAGELIMIT*dwPageSize, // size of allocation
                         MEM_RESERVE,        
                         PAGE_NOACCESS);     
  //
  // code to access memory 
  // ...
 
  if (lpvBase != NULL)
  {
    if (VirtualFree( lpvBase, 0, MEM_DECOMMIT )) // decommit pages
      {
        puts ("MEM_DECOMMIT Succeeded");
      }
      else
      {
       puts("MEM_DECOMMIT failed");
      }
  }
  else
  {
    puts("lpvBase == NULL");
  }
}

To correct this warning, use the following sample code:

#include <windows.h>
#include <stdio.h>
#define PAGELIMIT 80            

DWORD dwPages = 0;  // count of pages 
DWORD dwPageSize;   // page size 

VOID f( )
{
  LPVOID lpvBase;            // base address of the test memory
  SYSTEM_INFO sSysInfo;      // system information

  GetSystemInfo(&sSysInfo);  
  dwPageSize = sSysInfo.dwPageSize;

  // Reserve pages in the process's virtual address space
  lpvBase = VirtualAlloc(
                         NULL,                // system selects address
                         PAGELIMIT*dwPageSize, // size of allocation
                         MEM_RESERVE,        
                         PAGE_NOACCESS);     
  //
  // code to access memory 
  // ...
 
  if (lpvBase != NULL)
  {
   if (VirtualFree(lpvBase, 0,MEM_RELEASE )) // decommit & release 
   {
     // code ...
   }
   else
   {
     puts("MEM_RELEASE failed");
   }
  }
  else 
  {
    puts("lpvBase == Null ");
    // code...
  }
}