Memory Management

This overview describes how to use the memory management functions to allocate and use memory.

  • About Memory Management
  • Using the Virtual Memory Functions
  • Memory Management Reference
Microsoft Platform SDK, February 2001 Edition.
This content last built on Thursday, February 08, 2001.


About Memory Management

Each process has its own 32-bit virtual address space that enables addressing up to 4 gigabytes (GB) of memory. For information on the virtual address space and the memory management functions, see the following topics.

  • Virtual Address Space
  • Virtual Memory Functions
  • Heap Functions
  • Access Validation Functions
  • Global and Local Functions
  • Standard C Library Functions
  • Comparing Memory Allocation Methods


Virtual Address Space

The virtual addresses used by a process do not represent the actual physical location of an object in memory. Instead, the system maintains a page map for each process, which is an internal data structure used to translate virtual addresses into corresponding physical addresses.

The virtual address space is divided into partitions as follows.

Windows NT Server Enterprise Edition/Windows 2000 Advanced Server: The 3 GB partition in low memory (0x00000000 through 0xBFFFFFFF) is available to the process, and the 1 GB partition in high memory (0xC0000000 through 0xFFFFFFFF) is reserved for the system.

Windows NT/2000 or later: The 2 GB partition in low memory (0x00000000 through 0x7FFFFFFF) is available to the process, and the 2 GB partition in high memory (0x80000000 through 0xFFFFFFFF) is reserved for the system.

Windows 95/98/Me: The following are the partitions on Windows 95/98.

Range | Usage
0K - ~64K (0xFFFF) | Not writable. This boundary is approximate due to the way the Windows 95/98 loads some features of Microsoft® MS-DOS®. This memory is private to the process.
~64K (0x10000) - 4 MB (0x3FFFFF) | Reserved for MS-DOS compatibility. This memory is fully readable and writable by the process. However, this range of memory may have some MS-DOS–related structures or code in it, so processes should not arbitrarily read from or write to it. This memory is private to the process.
4MB (0x400000) - 2GB (0x7FFFFFFF) | Available for code and user data. User data is readable and writable by the process. Code is execute-only. This memory is private to the process.
2GB (0x80000000) - 3GB (0xBFFFFFFF) | Shared area, readable and writable by all processes. A number of system DLLs and other data are loaded into this space.
3GB (0xC0000000) - 4GB (0xFFFFFFFF) | System memory, readable or writable by any process. However, this is where low-level system code resides, so writing to this region may corrupt the system, with potentially catastrophic consequences.

For more information on virtual memory, see the following topics:

  • Virtual Address Space and Physical Storage
  • Page State
  • Scope of Allocated Memory


Virtual Address Space and Physical Storage

The virtual address space of each process is much larger than the total physical memory available to all processes. To increase the size of physical storage, the system uses the disk for additional storage. The total amount of storage available to all executing processes is the sum of the physical memory and the free space on disk available to the paging file, a disk file used to increase the amount of physical storage. Physical storage and the virtual address space of each process are organized into pages, units of memory, whose size depends on the host computer. For example, on x86 computers the host page size is 4 kilobytes.

To maximize its flexibility in managing memory, the system can move pages of physical memory to and from a paging file on disk. When a page is moved in physical memory, the system updates the page maps of the affected processes. When the system needs space in physical memory, it moves the least recently used pages of physical memory to the paging file. Manipulation of physical memory by the system is completely transparent to applications, which operate only in their virtual address spaces.


Page State

The pages of a process's virtual address space can be in one of the following states.

State | Description
Free | A free page is not currently accessible, but it is available to be committed or reserved.
Reserved | A reserved page is a block of the process's virtual address space that has been set aside for future use. The process cannot access a reserved page, and there is no physical storage associated with it. A reserved page reserves a range of virtual addresses that cannot be used subsequently by other allocation functions. A process can use the VirtualAlloc function to reserve pages of its address space and later to commit the reserved pages. It can use the VirtualFree function to release them.
Committed | A committed page is one for which physical storage (in memory or on disk) has been allocated. It can be protected to allow either no access or read-only access, or it can have read and write access. A process can use the VirtualAlloc function to allocate committed pages. The GlobalAlloc and LocalAlloc functions allocate committed pages with read/write access. A committed page allocated by VirtualAlloc can be decommitted by the VirtualFree function, which releases the page's storage and changes the state of the page to reserved.


Scope of Allocated Memory

All memory a process allocates by using the Win32 memory allocation functions (HeapAlloc, VirtualAlloc, GlobalAlloc, or LocalAlloc) is accessible only to the process. However, memory allocated by a DLL is allocated in the address space of the process that called the DLL and is not accessible to other processes using the same DLL. To create shared memory, you must use file mapping.

Named file mapping provides an easy way to create a block of shared memory. A process can specify a name when it uses the CreateFileMapping function to create a file-mapping object. Other processes can specify the same name to either the CreateFileMapping or OpenFileMapping function to obtain a handle to the mapping object.

Each process specifies its handle to the file-mapping object in the MapViewOfFile function to map a view of the file into its own address space. The views of all processes for a single file-mapping object are mapped into the same sharable pages of physical storage. However, the virtual addresses of the mapped views can vary from one process to another, unless the MapViewOfFileEx function is used to map the view at a specified address. Although sharable, the pages of physical storage used for a mapped file view are not global; they are not accessible to processes that have not mapped a view of the file.

Any pages committed by mapping a view of a file are released when the last process with a view of the mapping object either terminates or unmaps its view by calling the UnmapViewOfFile function. At this time, the specified file (if any) associated with the mapping object is updated. A specified file can also be forced to update by calling the FlushViewOfFile function.

For more information, see File Mapping. For an example of shared memory in a DLL, see Using Shared Memory in a Dynamic-Link Library.

If multiple processes have write access to shared memory, you must synchronize access to the memory. For more information, see Synchronization.


Virtual Memory Functions

The Microsoft® Win32® API provides a set of virtual memory functions that enable a process to manipulate or determine the status of pages in its virtual address space. They can perform the following operations:

  • Reserve a range of a process's virtual address space. Reserving address space does not allocate any physical storage, but it prevents other allocation operations from using the specified range. It does not affect the virtual address spaces of other processes. Reserving pages prevents needless consumption of physical storage, while enabling a process to reserve a range of its address space into which a dynamic data structure can grow. The process can allocate physical storage for this space, as needed.
  • Commit a range of reserved pages in a process's virtual address space so that physical storage (either in RAM or on disk) is accessible only to the allocating process.
  • Specify read/write, read-only, or no access for a range of committed pages. This differs from the standard allocation functions that always allocate pages with read/write access.
  • Free a range of reserved pages, making the range of virtual addresses available for subsequent allocation operations by the calling process.
  • Decommit a range of committed pages, releasing their physical storage and making it available for subsequent allocation by any process.
  • Lock one or more pages of committed memory into physical memory (RAM) so that the system cannot swap the pages out to the paging file.
  • Obtain information about a range of pages in the virtual address space of the calling process or a specified process.
  • Change the access protection for a specified range of committed pages in the virtual address space of the calling process or a specified process.

For more information, see the following topics.

  • Allocating Virtual Memory
  • Freeing Virtual Memory
  • Working With Pages


Allocating Virtual Memory

The virtual memory functions manipulate pages of memory. The functions use the size of a page on the current computer to round off specified sizes and addresses.

The VirtualAlloc function performs one of the following operations:

  • Reserves one or more free pages.
  • Commits one or more reserved pages.
  • Reserves and commits one or more free pages.

You can specify the starting address of the pages to be reserved or committed, or you can allow the system to determine the address. The function rounds the specified address to the appropriate page boundary. Reserved pages are not accessible, but committed pages can be allocated with PAGE_READWRITE, PAGE_READONLY, or PAGE_NOACCESS access. When pages are committed, storage is allocated in the paging file, but each page is initialized and loaded into physical memory only at the first attempt to read from or write to that page. You can use normal pointer references to access memory committed by the VirtualAlloc function.


Freeing Virtual Memory

The VirtualFree function performs one of the following operations:

  • Decommits one or more committed pages, changing the state of the pages to reserved. Decommitting pages releases the physical storage associated with the pages, making it available to be allocated by any process. Any block of committed pages can be decommitted.
  • Releases a block of one or more reserved pages, changing the state of the pages to free. Releasing a block of pages makes the range of reserved addresses available to be allocated by the process. Reserved pages can be released only by freeing the entire block that was initially reserved by VirtualAlloc.
  • Decommits and releases a block of one or more committed pages simultaneously, changing the state of the pages to free. The specified block must include the entire block initially reserved by VirtualAlloc, and all of the pages must be currently committed.

After a memory block is released or decommitted, you can never refer to it again. Any information that may have been in that memory is gone forever. Attempting to read from or write to a free page results in an access violation exception. If you require information, do not decommit or free memory containing that information.

To specify that the data in a memory range is no longer of interest, call VirtualAlloc with MEM_RESET. The pages will not be read from or written to the paging file. However, the memory block can be used again later.


Working with Pages

To determine the size of a page on the current computer, use the GetSystemInfo function.

The VirtualQuery and VirtualQueryEx functions return information about a region of consecutive pages beginning at a specified address in the address space of a process. VirtualQuery returns information about memory in the calling process. VirtualQueryEx returns information about memory in a specified process and is used to support debuggers that need information about a process being debugged. The region of pages is bounded by the specified address rounded down to the nearest page boundary. It extends through all subsequent pages with the following attributes in common:

  • The state of all pages is the same: either committed, reserved, or free.
  • If the initial page is not free, all pages in the region are part of the same initial allocation of pages that were reserved by a call to VirtualAlloc.
  • The access protection of all pages is the same (that is, PAGE_READONLY, PAGE_READWRITE, or PAGE_NOACCESS).

The VirtualLock function enables a process to lock one or more pages of committed memory into physical memory (RAM), preventing the system from swapping the pages out to the paging file. It can be used to ensure that critical data is accessible without disk access. Locking pages into memory is dangerous because it restricts the system's ability to manage memory. Excessive use of VirtualLock can degrade system performance by causing executable code to be swapped out to the paging file. The VirtualUnlock function unlocks memory locked by VirtualLock.

The VirtualProtect function enables a process to modify the access protection of any committed page in the address space of a process. For example, a process can allocate read/write pages to store sensitive data, and then it can change the access to read only or no access to protect against accidental overwriting. VirtualProtect is typically used with pages allocated by VirtualAlloc, but it also works with pages committed by any of the other allocation functions. However, VirtualProtect changes the protection of entire pages, and pointers returned by the other functions are not necessarily aligned on page boundaries. The VirtualProtectEx function is similar to VirtualProtect, except it changes the protection of memory in a specified process. Changing the protection is useful to debuggers in accessing the memory of a process being debugged.


Heap Functions

The heap functions enable a process to create a private heap, a block of one or more pages in the address space of the calling process. The process can then use a separate set of functions to manage the memory in that heap. There is no difference between memory allocated from a private heap and that allocated by using the other memory allocation functions.

The HeapCreate function creates a private heap object from which the calling process can allocate memory blocks by using the HeapAlloc function. HeapCreate specifies both an initial size and a maximum size for the heap. The initial size determines the number of committed, read/write pages initially allocated for the heap. The maximum size determines the total number of reserved pages. These pages create a contiguous block in the virtual address space of a process into which the heap can grow. Additional pages are automatically committed from this reserved space if requests by HeapAlloc exceed the current size of committed pages, assuming that the physical storage for it is available. Once the pages are committed, they are not decommitted until the process is terminated or until the heap is destroyed by calling the HeapDestroy function.

The memory of a private heap object is accessible only to the process that created it. If a dynamic-link library (DLL) creates a private heap, it does so in the address space of the process that called the DLL. It is accessible only to that process.

The HeapAlloc function allocates a specified number of bytes from a private heap and returns a pointer to the allocated block. The pointer identifies the block for the HeapFree function to release or for the HeapSize function to determine the size.

Memory allocated by HeapAlloc is not movable. Because the system cannot compact a private heap, the heap can become fragmented.

A possible use for the heap functions is to create a private heap when a process starts up, specifying an initial size sufficient to satisfy the memory requirements of the process. If the call to the HeapCreate function fails, the process can terminate or notify the user of the memory shortage; if it succeeds, however, the process is assured of having the memory it needs.

Memory requested by HeapCreate may or may not be contiguous. Memory allocated within a heap by HeapAlloc is contiguous. You should not write to or read from memory in a heap except that allocated by HeapAlloc, nor should you assume any relationship between two areas of memory allocated by HeapAlloc.

You should not refer in any way to memory that has been freed by HeapFree. Once that memory is freed, any information that may have been in it is gone forever. If you require information, do not free memory containing the information. Function calls that return information about memory (such as HeapSize) may not be used with freed memory, as they may return bogus data.

External factors may cause accesses to heap memory to generate access violations. One possible cause of an access violation is very limited space in the paging file. Therefore, all accesses to heap memory should be protected with structured exception handlers. For more information, see Structured Exception Handling.

Windows 95/98/Me: The heap managers are designed for memory blocks smaller than four megabytes. If you expect your memory blocks to be larger than one or two megabytes, you can avoid significant performance degradation by using the VirtualAlloc or VirtualAllocEx function instead.


Access Validation Functions

The Win32 API provides a set of functions that a process can use to verify whether it has a specified type of access to a given memory address or range of addresses. The following access validation functions are available.

Function | Description
IsBadCodePtr | Determines whether the calling process has read access to the memory at the specified address.
IsBadReadPtr | Determines whether the calling process has read access to the memory at a specified range of addresses.
IsBadStringPtr | Determines whether the calling process has read access to the memory pointed to by a null-terminated string pointer. The function validates access for a specified number of characters or until it encounters the string's terminating null character.
IsBadWritePtr | Determines whether the calling process has write access to the memory at a specified range of addresses.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when an access validation function indicates that the process has the desired access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception. For more information, see Structured Exception Handling.


Address Windowing Extensions

This topic describes the Address Windowing Extensions (AWE). These extensions provide user applications with 32-bit virtual addressing to greater than 32-bit regions of physical memory.

Windows NT and Windows 2000 have always provided applications with a flat 32-bit virtual address space, which describes 4 gigabytes (4GB) of virtual memory. The address space is usually split so that 2GB of address space is directly accessible to the application. The other 2GB is accessible only to the executive software. Additionally, with Windows NT 4.0 SP3, an option is provided on Windows NT Server Enterprise Edition/Windows 2000 Advanced Server x86 systems for applications to have a 3GB flat virtual address space, with the executive software using only 1GB.

AWE is a set of extensions that allows an application with the Lock Pages in Memory user right to use physical nonpaged memory and window views to various portions of this physical memory within a 32-bit virtual address space. In this way, applications are able to quickly manipulate physical memory greater than 4GB. Certain data-intensive applications, such as database management systems and scientific and engineering software, need access to very large caches of data. In the case of very large data sets, restricting the cache to fit within an application's 2GB of user address space is a severe restriction. In these situations, the cache is too small to properly support the application.

AWE solves this problem by allowing applications to directly address huge amounts of memory while continuing to use 32-bit pointers. AWE allows applications to have data caches larger than 4GB (where sufficient physical memory is present).

AWE places a few restrictions on how this memory may be used, primarily because these restrictions allow extremely fast mapping, remapping, and freeing. Fast memory management is important for these potentially enormous address spaces.

  • Virtual address ranges allocated for the AWE are not sharable with other processes (and therefore not inheritable). In fact, two different AWE virtual addresses within the same process are not allowed to map the same physical page. These restrictions provide fast remapping and cleanup when memory is freed.
  • The physical pages that can be allocated for an AWE region are limited by the number of physical pages present in the machine, since this memory is never paged – it is locked down until the application explicitly frees it or exits. The physical pages allocated for a given process can be mapped into any AWE virtual region within the same process. Applications that use AWE must be careful not to take so much physical memory that they cause other applications to page excessively or prevent creation of new processes or threads due to lack of resources. Use the GlobalMemoryStatusEx function to monitor physical memory use.
  • AWE virtual addresses are always read/write and cannot be protected via calls to VirtualProtect (that is, no read-only memory, noaccess memory, guard pages, and the like can be specified).
  • AWE address ranges cannot be used to buffer data for graphics or video calls.
  • An AWE memory range cannot be split, nor can pieces of it be deleted. Instead, the entire virtual address range must be deleted as a unit when deletion is required. This means you must specify MEM_RELEASE (and not MEM_DECOMMIT) when calling VirtualFree.
  • Applications that use AWE are not supported in emulation mode. That is, an x86 application that uses AWE functions must be recompiled to run on Windows 2000 on another processor, whereas most applications can run without recompiling under an emulator on other platforms.

This solution addresses the physical memory issues in a very general, widely applicable manner. Some of the benefits of AWE are:

  • A small group of new functions is defined to manipulate AWE memory.
  • AWE provides a very fast remapping capability. Remapping is done by manipulating virtual memory tables, not by moving data in physical memory.
  • AWE provides page size granularity appropriate to the processor (for example, 4K on x86), which is more useful to applications than large pages (for example, 2MB or 4MB on x86).

To obtain the Lock Pages in Memory privilege, an administrator must add the attribute "Lock Pages in Memory" to the user's User Rights Assignments. For more information on how to do this, see "User Rights" in the operating system help.

The following functions make up the Address Windowing Extensions (AWE) API.

Function | Description
VirtualAlloc VirtualAllocEx | Reserve a portion of virtual address space to use for AWE, using MEM_PHYSICAL.
AllocateUserPhysicalPages | Allocate physical memory for use with AWE.
MapUserPhysicalPages | Map (or invalidate) AWE virtual addresses onto any set of physical pages obtained with AllocateUserPhysicalPages.
MapUserPhysicalPagesScatter | Map (or invalidate) AWE virtual addresses onto any set of physical pages obtained with AllocateUserPhysicalPages, but with finer control than that provided by MapUserPhysicalPages.
FreeUserPhysicalPages | Free physical memory that was used for AWE.


Global and Local Functions

The global and local functions supported for porting from 16-bit code, or maintaining source code compatibility with 16-bit Windows. The global and local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

Win32 memory management does not provide a separate local heap and global heap, as 16-bit Windows does. As a result, there is no difference between the memory objects allocated by the GlobalAlloc and LocalAlloc functions. In addition, the change from a 16-bit segmented memory model to a 32-bit virtual memory model has made some of the related global and local functions and their options unnecessary or meaningless. For example, there are no longer near and far pointers, because both local and global allocations return 32-bit virtual addresses.

Memory objects allocated by GlobalAlloc and LocalAlloc are in private, committed pages with read/write access that cannot be accessed by other processes. Memory allocated by using GlobalAlloc with GMEM_DDESHARE is not actually shared globally as it is in 16-bit Windows. This value has no effect and is available only for compatibility. Applications requiring shared memory for other purposes must use file-mapping objects. Multiple processes can map a view of the same file-mapping object to provide named shared memory. For more information, see File Mapping.

Memory allocations are limited only by the available physical memory, including storage in the paging file on disk. When you allocate fixed memory, GlobalAlloc and LocalAlloc return a pointer that the calling process can immediately use to access the memory. When you allocate moveable memory, the return value is a handle. To get a pointer to a movable memory object, use the GlobalLock and LocalLock functions.

The actual size of the memory allocated can be larger than the requested size. To determine the actual number of bytes allocated, use the GlobalSize or LocalSize function. If the amount allocated is greater than the amount requested, the process can use the entire amount.

The GlobalReAlloc and LocalReAlloc functions change the size, in bytes, or the attributes of a memory object allocated by GlobalAlloc and LocalAlloc. The size can increase or decrease.

The GlobalFree and LocalFree functions release memory allocated by GlobalAlloc, LocalAlloc, GlobalReAlloc, or LocalReAlloc. To discard the specified memory object without invalidating the handle, use the GlobalDiscard or LocalDiscard function. The handle can be used later by GlobalReAlloc or LocalReAlloc to allocate a new block of memory associated with the same handle.

To return information about a specified memory object, use the GlobalFlags or LocalFlags function. The information includes the object's lock count and indicates whether the object is discardable or has already been discarded. To return a handle to the memory object associated with a specified pointer, use the GlobalHandle or LocalHandle function.

Windows 95/98/Me: The heap managers are designed for memory blocks smaller than four megabytes. If you expect your memory blocks to be larger than one or two megabytes, you can avoid significant performance degradation by using the VirtualAlloc or VirtualAllocEx function instead.


Standard C Library Functions

Win32-based applications can safely use the memory management features of the C run-time library (malloc, free, and so on) and C++ (new, delete, and so on). The C run-time library functions do not have the potential problems they have under 16-bit Windows. Memory management is no longer a problem because the system is free to manage memory by moving pages of physical memory without affecting the virtual addresses. Similarly, the distinction between near and far pointers is no longer relevant. Therefore, you can use the standard C library functions for memory management. However, the Win32 memory management functions do provide functionality that is unavailable in the C run-time library.


Comparing Memory Allocation Methods

This topic provides a brief comparison of the following memory allocation methods:

  • CoTaskMemAlloc
  • GlobalAlloc
  • HeapAlloc
  • LocalAlloc
  • malloc
  • new
  • VirtualAlloc

The following functions are equivalent: GlobalAlloc, LocalAlloc, and HeapAlloc with the handle returned by the GetProcessHeap function.

The VirtualAlloc function allows you to specify additional options for memory allocation. However, its allocations use a page granularity, so using VirtualAlloc can result in higher memory usage.

The malloc function has the disadvantage of being run-time dependent. The new operator has the disadvantage of being compiler dependant and language dependant.

The CoTaskMemAlloc function has the advantage of working well in either C, C++, or Visual Basic. It is also the only way to share memory in a COM-based application, since MIDL uses CoTaskMemAlloc and CoTaskMemFree to marshal memory.


Using the Virtual Memory Functions

  • Reserving and Committing Memory
  • Creating Guard Pages
  • AWE Example


Reserving and Committing Memory

The following example illustrates the use of the VirtualAlloc and VirtualFree functions in reserving and committing memory as needed for a dynamic array. First, VirtualAlloc is called to reserve a block of pages with NULL specified as the base address parameter, forcing the system to determine the location of the block. Later, VirtualAlloc is called whenever it is necessary to commit a page from this reserved region, and the base address of the next page to be committed is specified.

The example uses structured exception-handling syntax to commit pages from the reserved region. Whenever a page fault exception occurs during the execution of the __try block, the filter function in the expression preceding the __except block is executed. If the filter function can allocate another page, execution continues in the __try block at the point where the exception occurred. Otherwise, the exception handler in the __except block is executed. For more information, see Structured Exception Handling.

As an alternative to dynamic allocation, the process can simply commit the entire region instead of only reserving it. However, committing the region consumes physical storage that might not be needed, making it unavailable for use by other processes.

The example uses VirtualFree to free the reserved and committed pages when it is finished with them. The function is called twice: first to decommit the committed pages and again to release the entire region of reserved pages.

// A short program to demonstrate dynamic memory allocation using
// a structured exception handler.

#include <windows.h>
#include <stdio.h>              // for printf

#define PAGELIMIT 80            // ask for this many pages

LPTSTR lpNxtPage;               // address of the next page to ask for
DWORD dwPages = 0;              // count of pages gotten so far
DWORD dwPageSize;               // the page size on this computer

INT PageFaultExceptionFilter(DWORD dwCode)
{
  LPVOID lpvResult;

  // If the exception is not a page fault, exit.

  if (dwCode != EXCEPTION_ACCESS_VIOLATION)
    {
      printf("Exception code = %d\n", dwCode);
      return EXCEPTION_EXECUTE_HANDLER;
    }

  printf("Exception is a page fault\n");

  // If the reserved pages are used up, exit.

  if (dwPages >= PAGELIMIT)
    {
      printf("Exception: out of pages\n");
      return EXCEPTION_EXECUTE_HANDLER;
    }

  // Otherwise, commit another page.

  lpvResult = VirtualAlloc(
                           (LPVOID) lpNxtPage, // next page to commit
                           dwPageSize,         // page size, in bytes
                           MEM_COMMIT,         // allocate a committed page
                           PAGE_READWRITE);    // read/write access
  if (lpvResult == NULL )
    {
      printf("VirtualAlloc failed\n");
      return EXCEPTION_EXECUTE_HANDLER;
    } else {
      printf ("Allocating another page.\n");
    }

  // Increment the page count, and advance lpNxtPage to the next page.

  dwPages++;
  lpNxtPage += dwPageSize;

  // Continue execution where the page fault occurred.

  return EXCEPTION_CONTINUE_EXECUTION;
}

VOID ErrorExit(LPTSTR oops)
{
  printf ("Error! %s with error code of %ld\n",
          oops, GetLastError ());
  exit (0);
}

VOID main(VOID)
{
  LPVOID lpvBase;               // base address of the test memory
  LPTSTR lpPtr;                 // generic character pointer
  BOOL bSuccess;                // flag
  DWORD i;                      // generic counter
  SYSTEM_INFO sSysInfo;         // useful information about the system

  GetSystemInfo(&sSysInfo);     // populate the system information structure

  printf ("This computer has a page size of %d.\n", sSysInfo.dwPageSize);

  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,          // allocate reserved pages
                         PAGE_NOACCESS);       // protection = no access
  if (lpvBase == NULL )
    ErrorExit("VirtualAlloc reserve failed");

  lpPtr = lpNxtPage = (LPTSTR) lpvBase;

  // Use structured exception handling when accessing the pages.
  // If a page fault occurs, the exception filter is executed to
  // commit another page from the reserved block of pages.

  for (i=0; i < PAGELIMIT*dwPageSize; i++)
    {
      __try
        {
          // Write to memory.

          lpPtr[i] = 'a';
        }

      // If there's a page fault, commit another page and try again.

      __except ( PageFaultExceptionFilter( GetExceptionCode() ) )
        {

          // This is executed only if the filter function is unsuccessful
          // in committing the next page.

          ExitProcess( GetLastError() );

        }

    }

  // Release the block of pages when you are finished using them.

  bSuccess = VirtualFree(
                         lpvBase,            // base address of block
                         dwPages*dwPageSize, // bytes of committed pages
                         MEM_DECOMMIT| MEM_RELEASE); // decommit the pages

  printf ("Release was %s.\n", bSuccess ? "successful" : "unsuccessful" );
}


Creating Guard Pages

Windows NT/2000

A guard page provides a one-shot alarm for memory page access. This can be useful for an application that needs to monitor the growth of large dynamic data structures. For example, there are operating systems that use guard pages to implement automatic stack checking.

To create a guard page, set the PAGE_GUARD page protection modifier for the page. This value can be specified, along with other page protection modifiers, in the VirtualAlloc, VirtualAllocEx, VirtualProtect, and VirtualProtectEx functions. The PAGE_GUARD modifier can be used with any other page protection modifiers, except PAGE_NOACCESS.

If a program attempts to access an address within a guard page, the system raises a STATUS_GUARD_PAGE (0x80000001) exception. The system also clears the PAGE_GUARD modifier, removing the memory page's guard page status. The system will not stop the next attempt to access the memory page with a STATUS_GUARD_PAGE exception.

If a guard page exception occurs during a system service, the service fails and typically returns some failure status indicator. Since the system also removes the relevant memory page's guard page status, the next invocation of the same system service won't fail due to a STATUS_GUARD_PAGE exception (unless, of course, someone reestablishes the guard page).

The following short program illustrates the behavior of guard page protection.

/* A program to demonstrate the use of guard pages of memory. Allocate
   a page of memory as a guard page, then try to access the page. That
   will fail, but doing so releases the lock on the guard page, so the
   next access works correctly.

   The output will look something like this. The actual address may vary.

   This computer has a page size of 4096.
   Committed 4096 bytes at address 00520000
   Cannot lock at 00520000, error = 0x80000001
   2nd Lock Achieved at 00520000

   This sample does not show how to use the guard page fault to
   "grow" a dynamic array, such as a stack. */

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
  LPVOID lpvAddr;               // address of the test memory
  DWORD dwPageSize;             // amount of memory to allocate.
  BOOL bLocked;                 // address of the guarded memory
  SYSTEM_INFO sSysInfo;         // useful information about the system

  GetSystemInfo(&sSysInfo);     // populate the system information structure

  printf ("This computer has a page size of %d.\n", sSysInfo.dwPageSize);

  dwPageSize = sSysInfo.dwPageSize;

  // Try to allocate the memory.

  lpvAddr = VirtualAlloc(NULL, dwPageSize,
                         MEM_RESERVE | MEM_COMMIT,
                         PAGE_READONLY | PAGE_GUARD);

  if(lpvAddr == NULL) {
    printf("VirtualAlloc failed. Error: %ld\n",
           GetLastError());
    return 1;

  } else {
    fprintf(stderr, "Committed %lu bytes at address %lp\n",
            dwPageSize, lpvAddr);
  }

  // Try to lock the committed memory. This fails the first time because
  // of the guard page.

  bLocked = VirtualLock(lpvAddr, dwPageSize);
  if (!bLocked) {
    fprintf(stderr, "Cannot lock at %lp, error = 0x%lx\n",
            lpvAddr, GetLastError());
  } else {
    fprintf(stderr, "Lock Achieved at %lp\n", lpvAddr);
  }

  // Try to lock the committed memory again. This succeeds the second
  // time because the guard page status was removed by the first access
  // attempt.

  bLocked = VirtualLock(lpvAddr, dwPageSize);

  if (!bLocked) {
    fprintf(stderr, "Cannot get 2nd lock at %lp, error = %lx\n",
            lpvAddr, GetLastError());
  } else {
    fprintf(stderr, "2nd Lock Achieved at %lp\n", lpvAddr);
  }

  return 0;

}

Note The first attempt to lock the memory block fails, raising a STATUS_GUARD_PAGE exception. The second attempt succeeds, because the memory block's guard page protection has been toggled off by the first attempt.


AWE Example

The following sample program illustrates the Address Windowing Extensions for Windows 2000.

#include <windows.h>
#include <stdio.h>

#define MEMORY_REQUESTED 1024*1024 // request a megabyte

BOOL
LoggedSetLockPagesPrivilege ( HANDLE hProcess,
                              BOOL bEnable);

void _cdecl main()
{
  BOOL bResult;                 // generic Boolean value
  ULONG_PTR NumberOfPages,      // number of pages to request
    NumberOfPagesInitial;       // initial number of pages requested
  ULONG_PTR *aPFNs;             // page info; holds opaque data
  PVOID lpMemReserved;          // AWE window
  SYSTEM_INFO sSysInfo;         // useful system information
  int PFNArraySize;             // memory to request for PFN array

  GetSystemInfo(&sSysInfo);     // populate the system information structure

  printf ("This computer has a page size of %d.\n", sSysInfo.dwPageSize);

  // Calculate the number of pages of memory to request.

  NumberOfPages = MEMORY_REQUESTED/sSysInfo.dwPageSize;
  printf ("Requesting %d pages of memory.\n", NumberOfPages);

  // Calculate the size of the user PFN array.

  PFNArraySize = NumberOfPages * sizeof (ULONG_PTR);

  printf ("Requesting a PFN array of %d bytes.\n", PFNArraySize);

  aPFNs = (ULONG_PTR *) HeapAlloc (GetProcessHeap (), 0, PFNArraySize);

  if (aPFNs == NULL) {
    printf ("Failed to allocate on heap.\n");
    return;
  }

  // Enable the privilege.

  if( ! LoggedSetLockPagesPrivilege( GetCurrentProcess(), TRUE ) ) {
    return;
  }

  // Allocate the physical memory.

  NumberOfPagesInitial = NumberOfPages;
  bResult = AllocateUserPhysicalPages( GetCurrentProcess(),
                                       &NumberOfPages,
                                       aPFNs );

  if( bResult != TRUE )
  {
    printf("Cannot allocate physical pages, error %u.\n", GetLastError() );
    return;
  }

  if( NumberOfPagesInitial != NumberOfPages )
  {
    printf("Allocated only %p pages.\n", NumberOfPages );
    return;
  }

  // Reserve the virtual memory.

  lpMemReserved = VirtualAlloc( NULL,
                                MEMORY_REQUESTED,
                                MEM_RESERVE | MEM_PHYSICAL,
                                PAGE_READWRITE );

  if( lpMemReserved == NULL )
  {
    printf("Cannot reserve memory.\n");
    return;
  }

  // Map the physical memory into the window.

  bResult = MapUserPhysicalPages( lpMemReserved,
                                  NumberOfPages,
                                  aPFNs );

  if( bResult != TRUE )
  {
    printf("MapUserPhysicalPages failed to map, error %u.\n", GetLastError() );
    return;
  }

  // unmap

  bResult = MapUserPhysicalPages( lpMemReserved,
                                  NumberOfPages,
                                  NULL );

  if( bResult != TRUE )
  {
    printf("MapUserPhysicalPages failed to unmap, error %u.\n", GetLastError() );
    return;
  }

  // Free the physical pages.

  bResult = FreeUserPhysicalPages( GetCurrentProcess(),
                                   &NumberOfPages,
                                   aPFNs );

  if( bResult != TRUE )
  {
    printf("Cannot free physical pages, error %u.\n", GetLastError() );
    return;
  }

  // Free virtual memory.

  bResult = VirtualFree( lpMemReserved,
                         0,
                         MEM_RELEASE );
}

/*****************************************************************
   LoggedSetLockPagesPrivilege: a function to obtain, if possible, or
   release the privilege of locking physical pages.

   Inputs:

       HANDLE hProcess: Handle for the process for which the
       privilege is needed

       BOOL bEnable: Enable (TRUE) or disable?

   Return value: TRUE indicates success, FALSE failure.

*****************************************************************/
BOOL
LoggedSetLockPagesPrivilege ( HANDLE hProcess,
                              BOOL bEnable)
{
  struct {
    DWORD Count;
    LUID_AND_ATTRIBUTES Privilege [1];
  } Info;

  HANDLE Token;
  BOOL Result;

  // Open the token.

  Result = OpenProcessToken ( hProcess,
                              TOKEN_ADJUST_PRIVILEGES,
                              & Token);

  if( Result != TRUE ) {
    printf( "Cannot open process token.\n" );
    return FALSE;
  }

  // Enable or disable?

  Info.Count = 1;
  if( bEnable )
  {
    Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
  }
  else
  {
    Info.Privilege[0].Attributes = 0;
  }

  // Get the LUID.

  Result = LookupPrivilegeValue ( NULL,
                                  SE_LOCK_MEMORY_NAME,
                                  &(Info.Privilege[0].Luid));

  if( Result != TRUE )
  {
    printf( "Cannot get privilege value for %s.\n", SE_LOCK_MEMORY_NAME );
    return FALSE;
  }

  // Adjust the privilege.

  Result = AdjustTokenPrivileges ( Token, FALSE,
                                   (PTOKEN_PRIVILEGES) &Info,
                                   NULL, NULL, NULL);

  // Check the result.

  if( Result != TRUE )
  {
    printf ("Cannot adjust token privileges, error %u.\n", GetLastError() );
    return FALSE;
  }
  else
  {
    if( GetLastError() != ERROR_SUCCESS )
    {
      printf ("Cannot enable SE_LOCK_MEMORY privilege, please check the local policy.\n");
      return FALSE;
    }
  }

  CloseHandle( Token );

  return TRUE;
}


Memory Management Reference

The following elements are used with memory management.

  • Memory Management Functions
  • Memory Management Structures


Memory Management Functions

The following functions are used in memory management.

Function | Description
CopyMemory | Copies a block of memory from one location to another.
FillMemory | Fills a block of memory with a specified value.
GetWriteWatch | Retrieves the addresses of the pages that have been written to in a region of virtual memory.
GlobalMemoryStatus | Obtains information about the system's current usage of both physical and virtual memory.
GlobalMemoryStatusEx | Obtains information about the system's current usage of both physical and virtual memory.
IsBadCodePtr | Determines whether the calling process has read access to the memory at the specified address.
IsBadReadPtr | Verifies that the calling process has read access to the specified range of memory.
IsBadStringPtr | Verifies that the calling process has read access to a range of memory pointed to by a string pointer.
IsBadWritePtr | Verifies that the calling process has write access to the specified range of memory.
MoveMemory | Moves a block of memory from one location to another.
ResetWriteWatch | Resets the write-tracking state for a region of virtual memory.
ZeroMemory | Fills a block of memory with zeros.

The following are the AWE functions.

Function | Description
AllocateUserPhysicalPages | Allocates physical memory pages to be mapped and unmapped within any AWE region of the process.
FreeUserPhysicalPages | Frees physical memory pages previously allocated with AllocateUserPhysicalPages.
MapUserPhysicalPages | Maps previously allocated physical memory pages at the specified address within an AWE region.
MapUserPhysicalPagesScatter | Maps previously allocated physical memory pages at the specified address within an AWE region.

The following are the global and local functions. These functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

Function | Description
GlobalAlloc | Allocates the specified number of bytes from the heap.
GlobalDiscard | Discards the specified global memory block.
GlobalFlags | Returns information about the specified global memory object.
GlobalFree | Frees the specified global memory object.
GlobalHandle | Retrieves the handle associated with the specified pointer to a global memory block.
GlobalLock | Locks a global memory object and returns a pointer to the first byte of the object's memory block.
GlobalReAlloc | Changes the size or attributes of a specified global memory object.
GlobalSize | Retrieves the current size of the specified global memory object.
GlobalUnlock | Decrements the lock count associated with a memory object.
LocalAlloc | Allocates the specified number of bytes from the heap.
LocalDiscard | Discards the specified local memory object.
LocalFlags | Returns information about the specified local memory object.
LocalFree | Frees the specified local memory object.
LocalHandle | Retrieves the handle associated with the specified pointer to a local memory object.
LocalLock | Locks a local memory object and returns a pointer to the first byte of the object's memory block.
LocalReAlloc | Changes the size or the attributes of a specified local memory object.
LocalSize | Returns the current size of the specified local memory object.
LocalUnlock | Decrements the lock count associated with a memory object.

The following are the heap functions.

Function | Description
GetProcessHeap | Obtains a handle to the heap of the calling process.
GetProcessHeaps | Obtains handles to all of the heaps that are valid for the calling process.
HeapAlloc | Allocates a block of memory from a heap.
HeapCompact | Attempts to compact a specified heap.
HeapCreate | Creates a heap object.
HeapDestroy | Destroys the specified heap object.
HeapFree | Frees a memory block allocated from a heap.
HeapLock | Attempts to acquire the lock associated with a specified heap.
HeapReAlloc | Reallocates a block of memory from a heap.
HeapSize | Returns the size of a memory block allocated from a heap.
HeapUnlock | Releases ownership of the lock associated with a specified heap.
HeapValidate | Attempts to validate a specified heap.
HeapWalk | Enumerates the memory blocks in a specified heap.

The following are the virtual memory functions.

Function | Description
VirtualAlloc | Reserves or commits a region of pages in the virtual address space of the calling process.
VirtualAllocEx | Reserves or commits a region of pages in the virtual address space of the calling process.
VirtualFree | Releases or decommits a region of pages within the virtual address space of the calling process.
VirtualFreeEx | Releases or decommits a region of memory within the virtual address space of a specified process.
VirtualLock | Locks the specified region of the process's virtual address space into physical memory.
VirtualProtect | Changes the access protection on a region of committed pages in the virtual address space of the calling process.
VirtualProtectEx | Changes the access protection on a region of committed pages in the virtual address space of the calling process.
VirtualQuery | Provides information about a range of pages in the virtual address space of the calling process.
VirtualQueryEx | Provides information about a range of pages in the virtual address space of the calling process.
VirtualUnlock | Unlocks a specified range of pages in the virtual address space of a process.


AllocateUserPhysicalPages

The AllocateUserPhysicalPages function allocates physical memory pages to be mapped and unmapped within any Address Windowing Extensions (AWE) region of the specified process.

BOOL AllocateUserPhysicalPages(
  HANDLE hProcess,           // handle to process
  PULONG_PTR NumberOfPages,  // number of pages
  PULONG_PTR UserPfnArray    // address of storage
);

Parameters

hProcess
[in] Handle to a process. The function allocates memory within the virtual address space of this process. The user executing the calling application must have Lock Pages in Memory privileged access to this process. If you do not, the function fails.
NumberOfPages
[in/out] Specifies the size, in pages, of the physical memory to allocate. Use the GetSystemInfo function to determine the page size of the computer. This parameter also returns the number of pages actually allocated, which may be less than the number requested.
UserPfnArray
[out] Specifies the virtual address in which to store the page frame numbers of the allocated memory. The size of the memory allocated should be at least NumberOfPages times the size of the data type ULONG_PTR.

Do not attempt to modify this buffer. It contains operating system data, corruption of which could be catastrophic. There is no information in it that is useful to your application.

Return Values

If the function succeeds, the return value is TRUE. Fewer pages than requested may actually be allocated. The caller must check the value of the NumberOfPages parameter on return to see how many pages were allocated. All allocated page frame numbers are sequentially placed in the memory pointed to by the UserPfnArray parameter.

If the function fails, the return value is FALSE and no frames are allocated. To get extended error information, call GetLastError.

Remarks

The AllocateUserPhysicalPages function is used to allocate physical memory. Memory allocated by this function must be physically present in the system. Once allocated, it is locked down and unavailable to the rest of the virtual memory management system of Windows 2000.

Note that a given physical page cannot be simultaneously mapped at more than one virtual address.

Physical pages can reside at any physical address. You should make no assumptions about the contiguity of the physical pages.

Use the GetSystemInfo function to determine the page size of the computer.

For example, see AWE Example.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Address Windowing Extensions, MapUserPhysicalPages, MapUserPhysicalPagesScatter, FreeUserPhysicalPages, GetSystemInfo


CopyMemory

The CopyMemory function copies a block of memory from one location to another.

VOID CopyMemory(
  PVOID Destination,   // copy destination
  CONST VOID* Source,  // memory block
  SIZE_T Length        // size of memory block
);

Parameters

Destination
[in] Pointer to the starting address of the copied block's destination.
Source
[in] Pointer to the starting address of the block of memory to copy.
Length
[in] Specifies the size, in bytes, of the block of memory to copy.

Return Values

This function has no return value.

Remarks

If the source and destination blocks overlap, the results are undefined. For overlapped blocks, use the MoveMemory function.

Warning The first parameter, Destination, must be large enough to hold Length bytes of Source; otherwise, a buffer overrun may occur. This may lead to a denial of service attack against the application if an access violation occurs or, in the worst case, allow an attacker to inject executable code into your process. This is especially true if Destination is a stack-based buffer. Be aware that the last parameter, Length, is the number of bytes to copy into Destination, not the size of the Destination.

The following code example shows a safe way to use CopyMemory:

void test(char *pbData, unsigned int cbData) {
  char buf[BUFFER_SIZE];
  CopyMemory(buf, pbData, min(cbData,BUFFER_SIZE));
}

MAPI: For more information, see Syntax and Limitations for Win32 Functions Useful in MAPI Development.

For example, see Traversing the Module List.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.

See Also

Memory Management Overview, Memory Management Functions, FillMemory, MoveMemory, ZeroMemory


FillMemory

The FillMemory function fills a block of memory with a specified value.

VOID FillMemory (
  PVOID Destination,  // memory block
  SIZE_T Length,      // size of memory block
  BYTE Fill           // fill value
);

Parameters

Destination
[out] Pointer to the starting address of the block of memory to fill.
Length
[in] Specifies the size, in bytes, of the block of memory to fill.
Fill
[in] Specifies the byte value with which to fill the memory block.

Return Values

This function has no return value.

MAPI: For more information, see Syntax and Limitations for Win32 Functions Useful in MAPI Development.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.

See Also

Memory Management Overview, Memory Management Functions, CopyMemory, MoveMemory, ZeroMemory


FreeUserPhysicalPages

The FreeUserPhysicalPages function frees physical memory pages previously allocated with AllocateUserPhysicalPages. If any of these pages are currently mapped in the AWE region, they are automatically unmapped by this call. Note this does not affect the virtual address space occupied by the specified AWE region.

BOOL FreeUserPhysicalPages(
  HANDLE hProcess,            // handle to process
  PULONG_PTR NumberOfPages,   // pages to free
  PULONG_PTR UserPfnArray     // virtual address
);

Parameters

hProcess
[in] Handle to a process. The function frees memory within the virtual address space of this process.
NumberOfPages
[in/out] Specifies the size, in pages, of the physical memory to free. On return, if the function failed, this parameter indicates the number of pages freed.
UserPfnArray
[in] Specifies the virtual address to obtain the page frame numbers to free.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. In this case, the NumberOfPages parameter will reflect how many pages have actually been released. To get extended error information, call GetLastError.

Remarks

In a multiprocessor environment, this function maintains coherence of the hardware translation buffer. Upon return from this function, all threads on all processors are guaranteed to see the correct mapping.

For example, see AWE Example.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Address Windowing Extensions, AllocateUserPhysicalPages, MapUserPhysicalPages, MapUserPhysicalPagesScatter


GetProcessHeap

The GetProcessHeap function obtains a handle to the heap of the calling process. This handle can then be used in subsequent calls to the HeapAlloc, HeapReAlloc, HeapFree, and HeapSize functions.

HANDLE GetProcessHeap(VOID);

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is a handle to the calling process's heap.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The GetProcessHeap function allows you to allocate memory from the process heap without having to first create a heap with the HeapCreate function, as shown in this example:

HeapAlloc(GetProcessHeap(), 0, dwBytes);

Note The handle obtained by calling this function should not be used in calls to the HeapDestroy function.

To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

For example, see AWE Example.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapAlloc, HeapCreate, HeapDestroy, HeapFree, HeapReAlloc, HeapSize


GetProcessHeaps

The GetProcessHeaps function obtains handles to all of the heaps that are valid for the calling process.

DWORD GetProcessHeaps(
  DWORD NumberOfHeaps,  // maximum number of heap handles
  PHANDLE ProcessHeaps  // buffer for heap handles
);

Parameters

NumberOfHeaps
[in] Specifies the maximum number of heap handles that can be stored into the buffer pointed to by ProcessHeaps.
ProcessHeaps
[out] Pointer to a buffer to receive an array of heap handles.

Return Values

The return value is the number of heap handles that are valid for the calling process.

If the return value is less than or equal to NumberOfHeaps, it is also the number of heap handles stored into the buffer pointed to by ProcessHeaps.

If the return value is greater than NumberOfHeaps, the buffer pointed to by ProcessHeaps is too small to hold all the valid heap handles of the calling process.The function will have stored no handles into that buffer. In this situation, use the return value to allocate a buffer that is large enough to receive the handles, and call the function again.

If the return value is zero, the function has failed, because every process has at least one valid heap, the process heap. To get extended error information, call GetLastError.

Remarks

Use the GetProcessHeap function to obtain a handle to the process heap of the calling process. The GetProcessHeaps function obtains a handle to that heap, plus handles to any additional private heaps created by calling the HeapCreate function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.5 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapCreate


GetWriteWatch

The GetWriteWatch function retrieves the addresses of the pages that have been written to in a region of virtual memory.

UINT GetWriteWatch(
  DWORD dwFlags,          // write-tracking state
  PVOID lpBaseAddress,    // base address of region
  SIZE_T dwRegionSize,    // size of region
  PVOID  *lpAddresses,    // array of page addresses
  PULONG_PTR lpdwCount,   // number of addresses returned
  PULONG lpdwGranularity  // page size
);

Parameters

dwFlags
[in] Indicates whether the function resets the write-tracking state. To reset the write-tracking state, set this parameter to WRITE_WATCH_FLAG_RESET. If this parameter is zero, GetWriteWatch does not reset the write-tracking state. For more information, see the following Remarks section.
lpBaseAddress
[in] Specifies the base address of the memory region for which to retrieve write-tracking information. This address must be in a memory region that was allocated by the VirtualAlloc function using MEM_WRITE_WATCH.
dwRegionSize
[in] Specifies the size, in bytes, of the memory region for which to retrieve write-tracking information.
lpAddresses
[out] Pointer to a buffer that receives an array of page addresses in the memory region. The addresses indicate the pages that have been written to since the region was allocated or the write-tracking state was reset.
lpdwCount
[in/out] On input, this variable indicates the size, in array elements, of the lpAddresses array. On output, the variable receives the number of page addresses returned in the array.
lpdwGranularity
[out] Pointer to a variable that receives the page size, in bytes.

Return Values

If the function succeeds, the return value is zero.

If the function fails, the return value is a nonzero value.

Remarks

When you call the VirtualAlloc function to reserve or commit memory, you can specify MEM_WRITE_WATCH. This value causes the system to keep track of the pages in the committed memory region that have been written to. You can then call the GetWriteWatch function to retrieve the addresses of the pages that have been written to since the region was allocated or the write-tracking state was reset.

To reset the write-tracking state, set the WRITE_WATCH_FLAG_RESET value in the dwFlags parameter. Alternatively, you can call the ResetWriteWatch function to reset the write-tracking state. If you use ResetWriteWatch, however, you must ensure that no threads write to the region during the interval between the GetWriteWatch and ResetWriteWatch calls. Otherwise, there may be written pages that you fail to detect.

The GetWriteWatch function can be useful to profilers, debugging tools, or garbage collectors.

Requirements

Windows NT/2000 or later: Unsupported .
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, ResetWriteWatch, VirtualAlloc


GlobalAlloc

The GlobalAlloc function allocates the specified number of bytes from the heap. Win32 memory management does not provide a separate local heap and global heap.

Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE, the clipboard functions, and OLE data objects.

HGLOBAL GlobalAlloc(
  UINT uFlags,     // allocation attributes
  SIZE_T dwBytes   // number of bytes to allocate
);

Parameters

uFlags
[in] Specifies how to allocate memory. If zero is specified, the default is GMEM_FIXED. This parameter can be one or more of the following values, except for the incompatible combinations that are specifically noted.
Value | Meaning
GHND | Combines GMEM_MOVEABLE and GMEM_ZEROINIT.
GMEM_FIXED | Allocates fixed memory. The return value is a pointer.
GMEM_MOVEABLE Allocates movable memory. In Win32, memory blocks are never moved in physical memory, but they can be moved within the default heap.

The return value is a handle to the memory object. To translate the handle into a pointer, use the GlobalLock function.

This value cannot be combined with GMEM_FIXED.

GMEM_ZEROINIT | Initializes memory contents to zero.
GPTR | Combines GMEM_FIXED and GMEM_ZEROINIT.

The following values are obsolete.
Value | Meaning
GMEM_DDESHARE | Ignored. This value is provided only for compatibility with 16-bit Windows.
GMEM_DISCARDABLE Ignored. This value is provided only for compatibility with 16-bit Windows.

In Win32, you must explicitly call the GlobalDiscard function to discard a block.

This value cannot be combined with GMEM_FIXED.

GMEM_LOWER | Ignored. This value is provided only for compatibility with 16-bit Windows.
GMEM_NOCOMPACT | Ignored. This value is provided only for compatibility with 16-bit Windows.
GMEM_NODISCARD | Ignored. This value is provided only for compatibility with 16-bit Windows.
GMEM_NOT_BANKED | Ignored. This value is provided only for compatibility with 16-bit Windows.
GMEM_NOTIFY | Ignored. This value is provided only for compatibility with 16-bit Windows.
GMEM_SHARE | Ignored. This value is provided only for compatibility with 16-bit Windows.

dwBytes
[in] Specifies the number of bytes to allocate. If this parameter is zero and the uFlags parameter specifies GMEM_MOVEABLE, the function returns a handle to a memory object that is marked as discarded.

Return Values

If the function succeeds, the return value is a handle to the newly allocated memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

If the heap does not contain sufficient free space to satisfy the request, GlobalAlloc returns NULL. Because NULL is used to indicate an error, virtual address zero is never allocated. It is, therefore, easy to detect the use of a NULL pointer.

Memory allocated with this function is guaranteed to be aligned on an 8-byte boundary. All memory is created with execute access; no special function is required to execute dynamically generated code.

If this function succeeds, it allocates at least the amount of memory requested. If the actual amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual number of bytes allocated, use the GlobalSize function.

To free the memory, use the GlobalFree function.

Windows 95/98/Me: The heap managers are designed for memory blocks smaller than four megabytes. If you expect your memory blocks to be larger than one or two megabytes, you can avoid significant performance degradation by using the VirtualAlloc or VirtualAllocEx function instead.

For example, see Storing an Image.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalDiscard, GlobalFree, GlobalLock, GlobalSize


GlobalDiscard

The GlobalDiscard function discards the specified global memory block. The lock count of the memory object must be zero.

Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

HGLOBAL GlobalDiscard(
  HGLOBAL hglbMem  // handle to global memory object
);

Parameters

hglbMem
[in] Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the function succeeds, the return value is a handle to the memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Although GlobalDiscard discards the object's memory block, the handle to the object remains valid. The process can subsequently pass the handle to the GlobalReAlloc function to allocate another global memory block identified by the same handle.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalReAlloc


GlobalFlags

The GlobalFlags function returns information about the specified global memory object.

Note This function is provided only for compatibility with 16-bit versions of Windows.

UINT GlobalFlags(
  HGLOBAL hMem   // handle to global memory object
);

Parameters

hMem
[in] Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the function succeeds, the return value specifies the allocation values and the lock count for the memory object.

If the function fails, the return value is GMEM_INVALID_HANDLE, indicating that the global handle is not valid. To get extended error information, call GetLastError.

Remarks

The low-order byte of the low-order word of the return value contains the lock count of the object. To retrieve the lock count from the return value, use the GMEM_LOCKCOUNT mask with the bitwise AND (&) operator. The lock count of memory objects allocated with GMEM_FIXED is always zero.

The high-order byte of the low-order word of the return value indicates the allocation values of the memory object. It can be zero or any combination of the following values.

Value | Meaning
GMEM_DDESHARE | Ignored. This value is provided only for compatibility with 16-bit Windows.
GMEM_DISCARDABLE | Ignored. This value is provided only for compatibility with 16-bit Windows. In Win32, you must explicitly call the GlobalDiscard function to discard a block.
GMEM_DISCARDED | The object's memory block has been discarded.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalDiscard, GlobalReAlloc


GlobalFree

The GlobalFree function frees the specified global memory object and invalidates its handle.

Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

HGLOBAL GlobalFree(
  HGLOBAL hMem   // handle to global memory object
);

Parameters

hMem
[in] Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the function succeeds, the return value is NULL.

If the function fails, the return value is equal to a handle to the global memory object. To get extended error information, call GetLastError.

Remarks

If the process examines or modifies the memory after it has been freed, heap corruption may occur or an access violation exception (EXCEPTION_ACCESS_VIOLATION) may be generated.

If the hgblMem parameter is NULL, GlobalFree fails and the system generates an access violation exception.

The GlobalFree function will free a locked memory object. A locked memory object has a lock count greater than zero. The GlobalLock function locks a global memory object and increments the lock count by one. The GlobalUnlock function unlocks it and decrements the lock count by one. To get the lock count of a global memory object, use the GlobalFlags function.

If an application is running under a debug version of the system, GlobalFree will issue a message that tells you that a locked object is being freed. If you are debugging the application, GlobalFree will enter a breakpoint just before freeing a locked object. This allows you to verify the intended behavior, then continue execution.

For example, see Storing an Image.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalFlags, GlobalLock, GlobalReAlloc, GlobalUnlock


GlobalHandle

The GlobalHandle function retrieves the handle associated with the specified pointer to a global memory block.

Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

HGLOBAL GlobalHandle(
  LPCVOID pMem   // first byte of global memory block
);

Parameters

pMem
[in] Pointer to the first byte of the global memory block. This pointer is returned by the GlobalLock function.

Return Values

If the function succeeds, the return value is a handle to the specified global memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

When the GlobalAlloc function allocates a memory object with GMEM_MOVEABLE, it returns a handle to the object. The GlobalLock function converts this handle into a pointer to the memory block, and GlobalHandle converts the pointer back into a handle.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalLock


GlobalLock

The GlobalLock function locks a global memory object and returns a pointer to the first byte of the object's memory block.

Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

LPVOID GlobalLock(
  HGLOBAL hMem   // handle to global memory object
);

Parameters

hMem
[in] Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the function succeeds, the return value is a pointer to the first byte of the memory block.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, GlobalLock increments the count by one, and the GlobalUnlock function decrements the count by one. For each call that a process makes to GlobalLock for an object, it must eventually call GlobalUnlock. Locked memory will not be moved or discarded, unless the memory object is reallocated by using the GlobalReAlloc function. The memory block of a locked memory object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded.

Memory objects allocated with GMEM_FIXED always have a lock count of zero. For these objects, the value of the returned pointer is equal to the value of the specified handle.

If the specified memory block has been discarded or if the memory block has a zero-byte size, this function returns NULL.

Discarded objects always have a lock count of zero.

For example, see Example of a Clipboard Viewer.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalReAlloc, GlobalUnlock


GlobalMemoryStatus

The GlobalMemoryStatus function obtains information about the system's current usage of both physical and virtual memory.

To obtain information about the extended portion of the virtual address space, or if your application may run on computers with more than 4 GB of main memory, use the GlobalMemoryStatusEx function.

VOID GlobalMemoryStatus(
  LPMEMORYSTATUS lpBuffer   // memory status structure
);

Parameters

lpBuffer
[out] Pointer to a MEMORYSTATUS structure. The GlobalMemoryStatus function stores information about current memory availability into this structure.

Return Values

This function does not return a value.

Remarks

You can use the GlobalMemoryStatus function to determine how much memory your application can allocate without severely impacting other applications.

The information returned by the GlobalMemoryStatus function is volatile. There is no guarantee that two sequential calls to this function will return the same information.

On computers with more than 4 GB of memory, the GlobalMemoryStatus function can return incorrect information. Windows 2000 reports a value of -1 to indicate an overflow. Earlier versions of Windows NT report a value that is the real amount of memory, modulo 4 GB. For this reason, on Windows 2000, use the GlobalMemoryStatusEx function instead.

On Intel x86 computers with more than 2 GB and less than 4 GB of memory, the GlobalMemoryStatus function will always return 2 GB in the dwTotalPhys member of the MEMORYSTATUS structure. Similarly, if the total available memory is between 2 and 4 GB, the dwAvailPhys member of the MEMORYSTATUS structure will be rounded down to 2 GB. If the executable is linked using the /LARGEADDRESSWARE linker option, then the GlobalMemoryStatus function will return the correct amount of physical memory in both members.

Example

The program following shows a simple use of the GlobalMemoryStatus function.

//  Sample output:
//  c:\>global
//  The MemoryStatus structure is 32 bytes long.
//  It should be 32.
//  78 percent of memory is in use.
//  There are   65076 total Kbytes of physical memory.
//  There are   13756 free Kbytes of physical memory.
//  There are  150960 total Kbytes of paging file.
//  There are   87816 free Kbytes of paging file.
//  There are  1fff80 total Kbytes of virtual memory.
//  There are  1fe770 free Kbytes of virtual memory.

#include <windows.h>

// Use to change the divisor from Kb to Mb.

#define DIV 1024
// #define DIV 1

char *divisor = "K";
// char *divisor = "";

// Handle the width of the field in which to print numbers this way to
// make changes easier. The asterisk in the print format specifier
// "%*ld" takes an int from the argument list, and uses it to pad and
// right-justify the number being formatted.
#define WIDTH 7

void main(int argc, char *argv[])
{
  MEMORYSTATUS stat;

  GlobalMemoryStatus (&stat);

  printf ("The MemoryStatus structure is %ld bytes long.\n",
          stat.dwLength);
  printf ("It should be %d.\n", sizeof (stat));
  printf ("%ld percent of memory is in use.\n",
          stat.dwMemoryLoad);
  printf ("There are %*ld total %sbytes of physical memory.\n",
          WIDTH, stat.dwTotalPhys/DIV, divisor);
  printf ("There are %*ld free %sbytes of physical memory.\n",
          WIDTH, stat.dwAvailPhys/DIV, divisor);
  printf ("There are %*ld total %sbytes of paging file.\n",
          WIDTH, stat.dwTotalPageFile/DIV, divisor);
  printf ("There are %*ld free %sbytes of paging file.\n",
          WIDTH, stat.dwAvailPageFile/DIV, divisor);
  printf ("There are %*lx total %sbytes of virtual memory.\n",
          WIDTH, stat.dwTotalVirtual/DIV, divisor);
  printf ("There are %*lx free %sbytes of virtual memory.\n",
          WIDTH, stat.dwAvailVirtual/DIV, divisor);
}

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalMemoryStatusEx, MEMORYSTATUS


GlobalMemoryStatusEx

The GlobalMemoryStatusEx function obtains information about the system's current usage of both physical and virtual memory.

BOOL GlobalMemoryStatusEx(
  LPMEMORYSTATUSEX lpBuffer   // memory status structure
);

Parameters

lpBuffer
[in/out] Pointer to a MEMORYSTATUSEX structure. GlobalMemoryStatusEx stores information about current memory availability in this structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

You can use the GlobalMemoryStatusEx function to determine how much memory your application can allocate without severely impacting other applications.

The information returned by the GlobalMemoryStatusEx function is volatile. There is no guarantee that two sequential calls to this function will return the same information.

Example

The program following shows a simple use of the GlobalMemoryStatusEx function.

//  Sample output:

//  c:\>globalex
//  78 percent of memory is in use.
//  There are   65076 total Kbytes of physical memory.
//  There are   14248 free Kbytes of physical memory.
//  There are  150960 total Kbytes of paging file.
//  There are   88360 free Kbytes of paging file.
//  There are  1fff80 total Kbytes of virtual memory.
//  There are  1fe770 free Kbytes of virtual memory.
//  There are       0 free Kbytes of extended memory.

#define _WIN32_WINNT 0x0500

#include <windows.h>

// Use to change the divisor from Kb to Mb.

#define DIV 1024
// #define DIV 1

char *divisor = "K";
// char *divisor = "";

// Handle the width of the field in which to print numbers this way to
// make changes easier. The asterisk in the print format specifier
// "%*I64d" takes an int from the argument list, and uses it to pad
// and right-justify the number being formatted.
#define WIDTH 7

void main(int argc, char *argv[])
{
  MEMORYSTATUSEX statex;

  statex.dwLength = sizeof (statex);

  GlobalMemoryStatusEx (&statex);

  printf ("%ld percent of memory is in use.\n",
          statex.dwMemoryLoad);
  printf ("There are %*I64d total %sbytes of physical memory.\n",
          WIDTH, statex.ullTotalPhys/DIV, divisor);
  printf ("There are %*I64d free %sbytes of physical memory.\n",
          WIDTH, statex.ullAvailPhys/DIV, divisor);
  printf ("There are %*I64d total %sbytes of paging file.\n",
          WIDTH, statex.ullTotalPageFile/DIV, divisor);
  printf ("There are %*I64d free %sbytes of paging file.\n",
          WIDTH, statex.ullAvailPageFile/DIV, divisor);
  printf ("There are %*I64x total %sbytes of virtual memory.\n",
          WIDTH, statex.ullTotalVirtual/DIV, divisor);
  printf ("There are %*I64x free %sbytes of virtual memory.\n",
          WIDTH, statex.ullAvailVirtual/DIV, divisor);

  // Show the amount of extended memory available.

  printf ("There are %*I64x free %sbytes of extended memory.\n",
          WIDTH, statex.ullAvailExtendedVirtual/DIV, divisor);

}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, MEMORYSTATUSEX


GlobalReAlloc

The GlobalReAlloc function changes the size or attributes of a specified global memory object. The size can increase or decrease.

Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

HGLOBAL GlobalReAlloc(
  HGLOBAL hMem,   // handle to global memory object
  SIZE_T dwBytes, // new block size
  UINT uFlags     // how to reallocate object
);

Parameters

hMem
[in] Handle to the global memory object to be reallocated. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.
dwBytes
[in] Specifies the new size, in bytes, of the memory block. If uFlags specifies GMEM_MODIFY, this parameter is ignored.
uFlags
[in] Specifies how to reallocate the global memory object. If GMEM_MODIFY is specified, this parameter modifies the attributes of the memory object, and the dwBytes parameter is ignored. Otherwise, this parameter controls the reallocation of the memory object.

You can combine GMEM_MODIFY with one or both of the following values.
Value Meaning
GMEM_DISCARDABLE Ignored. This value is provided only for compatibility with 16-bit Windows.

In Win32, you must explicitly call the GlobalDiscard function to discard a block.

In 16-bit Windows, allocates discardable memory, if GMEM_MODIFY is also specified. This value is ignored if the object was not previously allocated as movable or if GMEM_MOVEABLE is not specified.
GMEM_MOVEABLE If GMEM_MODIFY is also specified, GMEM_MOVEABLE changes a fixed memory object to a movable memory object.

If GMEM_MODIFY is not specified, then GMEM_MOVEABLE allows a locked GMEM_MOVEABLE memory block or a GMEM_FIXED memory block to be moved to a new fixed location. If neither GMEM_MODIFY nor GMEM_MOVEABLE is set, then fixed memory blocks and locked movable memory blocks will only be reallocated in place.

If this parameter does not specify GMEM_MODIFY, it can also be any combination of the following values.
Value | Meaning
GMEM_NOCOMPACT | Ignored. This value is provided only for compatibility with 16-bit Windows.
GMEM_ZEROINIT | Causes the additional memory contents to be initialized to zero if the memory object is growing in size.

Return Values

If the function succeeds, the return value is a handle to the reallocated memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

If GlobalReAlloc reallocates a movable object, the return value is a handle to the memory object. To convert the handle to a pointer, use the GlobalLock function.

If GlobalReAlloc reallocates a fixed object, the value of the handle returned is the address of the first byte of the memory block. To access the memory, a process can simply cast the return value to a pointer.

If GlobalReAlloc fails, the original memory is not freed, and the original handle and pointer are still valid.

Windows 95/98/Me: The heap managers are designed for memory blocks smaller than four megabytes. If you expect your memory blocks to be larger than one or two megabytes, you can avoid significant performance degradation by using the VirtualAlloc or VirtualAllocEx function instead.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalDiscard, GlobalLock


GlobalSize

The GlobalSize function retrieves the current size, in bytes, of the specified global memory object.

Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

SIZE_T GlobalSize(
  HGLOBAL hMem   // handle to global memory object
);

Parameters

hMem
[in] Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the function succeeds, the return value is the size, in bytes, of the specified global memory object.

If the specified handle is not valid or if the object has been discarded, the return value is zero. To get extended error information, call GetLastError.

Remarks

The size of a memory block may be larger than the size requested when the memory was allocated.

To verify that the specified object's memory block has not been discarded, use the GlobalFlags function before calling GlobalSize.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalFlags, GlobalReAlloc


GlobalUnlock

The GlobalUnlock function decrements the lock count associated with a memory object that was allocated with GMEM_MOVEABLE. This function has no effect on memory objects allocated with GMEM_FIXED.

Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

BOOL GlobalUnlock(
  HGLOBAL hMem   // handle to global memory object
);

Parameters

hMem
[in] Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the memory object is still locked after decrementing the lock count, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If GetLastError returns NO_ERROR, the memory object is unlocked.

Remarks

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, the GlobalLock function increments the count by one, and GlobalUnlock decrements the count by one. For each call that a process makes to GlobalLock for an object, it must eventually call GlobalUnlock. Locked memory will not be moved or discarded, unless the memory object is reallocated by using the GlobalReAlloc function. The memory block of a locked memory object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded.

Memory objects allocated with GMEM_FIXED always have a lock count of zero. If the specified memory block is fixed memory, this function returns TRUE.

If the memory object is already unlocked, GlobalUnlock returns FALSE and GetLastError reports ERROR_NOT_LOCKED.

A process should not rely on the return value to determine the number of times it must subsequently call GlobalUnlock for a memory object.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalLock, GlobalReAlloc


HeapAlloc

The HeapAlloc function allocates a block of memory from a heap. The allocated memory is not movable.

LPVOID HeapAlloc(
  HANDLE hHeap,   // handle to private heap block
  DWORD dwFlags,  // heap allocation control
  SIZE_T dwBytes  // number of bytes to allocate
);

Parameters

hHeap
[in] Specifies the heap from which the memory will be allocated. This parameter is a handle returned by the HeapCreate or GetProcessHeap function.
dwFlags
[in] Specifies several controllable aspects of heap allocation. Specifying any of these values will override the corresponding value specified when the heap was created with HeapCreate. This parameter can be one or more of the following values.
Value | Meaning
HEAP_GENERATE_EXCEPTIONS | Specifies that the system will raise an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.
HEAP_NO_SERIALIZE Specifies that mutual exclusion will not be used while the HeapAlloc function is accessing the heap.

This value should not be specified when accessing the process heap. The system may create additional threads within the application's process, such as a CTRL+C handler, that simultaneously access the process heap.

HEAP_ZERO_MEMORY | Specifies that the allocated memory will be initialized to zero. Otherwise, the memory is not initialized to zero.

dwBytes
[in] Specifies the number of bytes to be allocated.

If the heap specified by the hHeap parameter is a "non-growable" heap, dwBytes must be less than 0x7FFF8. You create a non-growable heap by calling the HeapCreate function with a nonzero value.

Return Values

If the function succeeds, the return value is a pointer to the allocated memory block.

If the function fails and you have not specified HEAP_GENERATE_EXCEPTIONS, the return value is NULL.

If the function fails and you have specified HEAP_GENERATE_EXCEPTIONS, the function may generate the following exceptions:

Value | Meaning
STATUS_NO_MEMORY | The allocation attempt failed because of a lack of available memory or heap corruption.
STATUS_ACCESS_VIOLATION | The allocation attempt failed because of heap corruption or improper function parameters.

Note Heap corruption can lead to either exception. It depends upon the nature of the heap corruption.

If the function fails, it does not call SetLastError. An application cannot call GetLastError for extended error information.

Remarks

If HeapAlloc succeeds, it allocates at least the amount of memory requested. If the actual amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual size of the allocated block, use the HeapSize function.

To free a block of memory allocated by HeapAlloc, use the HeapFree function.

Memory allocated by HeapAlloc is not movable. Since the memory is not movable, it is possible for the heap to become fragmented.

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE value eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE value can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

Windows 95/98/Me: The heap managers are designed for memory blocks smaller than four megabytes. If you expect your memory blocks to be larger than one or two megabytes, you can avoid significant performance degradation by using the VirtualAlloc or VirtualAllocEx function instead.

For example, see AWE Example.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapCreate, HeapDestroy, HeapFree, HeapReAlloc, HeapSize, SetLastError


HeapCompact

The HeapCompact function attempts to compact a specified heap. It compacts the heap by coalescing adjacent free blocks of memory and decommitting large free blocks of memory.

UINT HeapCompact(
  HANDLE hHeap,  // handle to heap
  DWORD dwFlags  // heap access options
);

Parameters

hHeap
[in] Handle to the heap that the function will attempt to compact.
dwFlags
[in] Specifies heap access during function operation. This parameter can be the following value.
Value | Meaning
HEAP_NO_SERIALIZE | Specifies that mutual exclusion will not be used while the HeapCompact function accesses the heap.

Return Values

If the function succeeds, the return value is the size, in bytes, of the largest committed free block in the heap. This is an unsigned integer value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

In the unlikely case that there is absolutely no space available in the heap, the function return value is zero, and GetLastError returns the value NO_ERROR.

Remarks

There is no guarantee that an application can successfully allocate a memory block of the size returned by HeapCompact. Other threads or the commit threshold might prevent such an allocation.

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE value eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE value can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.5 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapCreate, HeapValidate


HeapCreate

The HeapCreate function creates a heap object that can be used by the calling process. The function reserves space in the virtual address space of the process and allocates physical storage for a specified initial portion of this block.

HANDLE HeapCreate(
  DWORD flOptions,       // heap allocation attributes
  SIZE_T dwInitialSize,  // initial heap size
  SIZE_T dwMaximumSize   // maximum heap size
);

Parameters

flOptions
[in] Specifies optional attributes for the new heap. These options affect subsequent access to the new heap through calls to the heap functions (HeapAlloc, HeapFree, HeapReAlloc, and HeapSize). You can specify one or more of the following values.
Value | Meaning
HEAP_GENERATE_EXCEPTIONS | Specifies that the system will raise an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.
HEAP_NO_SERIALIZE | Specifies that mutual exclusion will not be used when the heap functions allocate and free memory from this heap. The default, when HEAP_NO_SERIALIZE is not specified, is to serialize access to the heap. Serialization of heap access allows two or more threads to simultaneously allocate and free memory from the same heap.

dwInitialSize
[in] Specifies the initial size, in bytes, of the heap. This value determines the initial amount of physical storage that is allocated for the heap. The value is rounded up to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.
dwMaximumSize
[in] If dwMaximumSize is a nonzero value, it specifies the maximum size, in bytes, of the heap. The HeapCreate function rounds dwMaximumSize up to the next page boundary, and then reserves a block of that size in the process's virtual address space for the heap. If allocation requests made by the HeapAlloc or HeapReAlloc functions exceed the initial amount of physical storage specified by dwInitialSize, the system allocates additional pages of physical storage for the heap, up to the heap's maximum size.

In addition, if dwMaximumSize is nonzero, the heap cannot grow, and an absolute limitation arises: the maximum size of a memory block in the heap is a bit less than 0x7FFF8 bytes. Requests to allocate larger blocks will fail, even if the maximum size of the heap is large enough to contain the block.

If dwMaximumSize is zero, it specifies that the heap is growable. The heap's size is limited only by available memory. Requests to allocate blocks larger than 0x7FFF8 bytes do not automatically fail; the system calls VirtualAlloc to obtain the memory needed for such large blocks. Applications that need to allocate large memory blocks should set dwMaximumSize to zero.

Return Values

If the function succeeds, the return value is a handle to the newly created heap.

If the function fails, the return value is is NULL. To get extended error information, call GetLastError.

Remarks

The HeapCreate function creates a private heap object from which the calling process can allocate memory blocks by using the HeapAlloc function. The initial size determines the number of committed pages that are initially allocated for the heap. The maximum size determines the total number of reserved pages. These pages create a block in the process's virtual address space into which the heap can grow. If requests by HeapAlloc exceed the current size of committed pages, additional pages are automatically committed from this reserved space, assuming that the physical storage is available.

The memory of a private heap object is accessible only to the process that created it. If a dynamic-link library (DLL) creates a private heap, the heap is created in the address space of the process that called the DLL, and it is accessible only to that process.

The system uses memory from the private heap to store heap support structures, so not all of the specified heap size is available to the process. For example, if the HeapAlloc function requests 64 kilobytes (K) from a heap with a maximum size of 64K, the request may fail because of system overhead.

If HEAP_NO_SERIALIZE is not specified (the simple default), the heap will serialize access within the calling process. Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap.

Setting HEAP_NO_SERIALIZE eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. Therefore, HEAP_NO_SERIALIZE can safely be used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, GetProcessHeaps, GetSystemInfo, HeapAlloc, HeapDestroy, HeapFree, HeapReAlloc, HeapSize, HeapValidate, VirtualAlloc


HeapDestroy

The HeapDestroy function destroys the specified heap object. HeapDestroy decommits and releases all the pages of a private heap object, and it invalidates the handle to the heap.

BOOL HeapDestroy(
  HANDLE hHeap   // handle to heap
);

Parameters

hHeap
[in] Specifies the heap to be destroyed. This parameter should be a heap handle returned by the HeapCreate function. Do not use the handle to the process heap returned by the GetProcessHeap function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Processes can call HeapDestroy without first calling the HeapFree function to free memory allocated from the heap.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapAlloc, HeapCreate, HeapFree, HeapReAlloc, HeapSize


HeapFree

The HeapFree function frees a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function.

BOOL HeapFree(
  HANDLE hHeap,  // handle to heap
  DWORD dwFlags, // heap free options
  LPVOID lpMem   // pointer to memory
);

Parameters

hHeap
[in] Specifies the heap whose memory block the function frees. This parameter is a handle returned by the HeapCreate or GetProcessHeap function.
dwFlags
[in] Specifies several controllable aspects of freeing a memory block. Specifying the following value overrides the corresponding value specified in the flOptions parameter when the heap was created by using the HeapCreate function.
Value Meaning
HEAP_NO_SERIALIZE Specifies that mutual exclusion will not be used while HeapFree is accessing the heap.

Do not specify this value when accessing the process heap. The system may create additional threads within the application's process, such as a CTRL+C handler, that simultaneously access the process heap.

lpMem
[in] Pointer to the memory block to free. This pointer is returned by the HeapAlloc or HeapReAlloc function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. An application can call GetLastError for extended error information.

Remarks

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE value eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE value can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

You should not refer in any way to memory that has been freed by HeapFree. Once that memory is freed, any information that may have been in it is gone forever. If you require information, do not free memory containing the information. Function calls that return information about memory (such as HeapSize) may not be used with freed memory, as they may return bogus data.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapAlloc, HeapCreate, HeapDestroy, HeapReAlloc, HeapSize, SetLastError


HeapLock

The HeapLock function attempts to acquire the critical section object, or lock, that is associated with a specified heap.

If the function succeeds, the calling thread owns the heap lock. Only the calling thread will be able to allocate or release memory from the heap. The execution of any other thread of the calling process will be blocked if that thread attempts to allocate or release memory from the heap. Such threads will remain blocked until the thread that owns the heap lock calls the HeapUnlock function.

BOOL HeapLock(
  HANDLE hHeap   // handle to heap
);

Parameters

hHeap
[in] Handle to the heap to lock for exclusive access by the calling thread.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The HeapLock function is primarily useful for preventing the allocation and release of heap memory by other threads while the calling thread uses the HeapWalk function.

Each call to HeapLock must be matched by a corresponding call to the HeapUnlock function. Failure to call HeapUnlock will block the execution of any other threads of the calling process that attempt to access the heap.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.5 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapUnlock, HeapWalk


HeapReAlloc

The HeapReAlloc function reallocates a block of memory from a heap. This function enables you to resize a memory block and change other memory block properties. The allocated memory is not movable.

LPVOID HeapReAlloc(
  HANDLE hHeap,   // handle to heap block
  DWORD dwFlags,  // heap reallocation options
  LPVOID lpMem,   // pointer to memory to reallocate
  SIZE_T dwBytes  // number of bytes to reallocate
);

Parameters

hHeap
[in] Heap from which the memory will be reallocated. This is a handle returned by the HeapCreate or GetProcessHeap function.
dwFlags
[in] Specifies several controllable aspects of heap reallocation. Specifying a value overrides the corresponding value specified in the flOptions parameter when the heap was created by using the HeapCreate function. This parameter can be one or more of the following values.
Value | Meaning
HEAP_GENERATE_EXCEPTIONS | Specifies that the operating-system raises an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.
HEAP_NO_SERIALIZE Specifies that mutual exclusion is not used while HeapReAlloc is accessing the heap.

This value should not be specified when accessing the process heap. The system may create additional threads within the application's process, such as a CTRL+C handler, that simultaneously access the process heap.

HEAP_REALLOC_IN_PLACE_ONLY | Specifies that there can be no movement when reallocating a memory block to a larger size. If this value is not specified and the reallocation request is for a larger size, the function may move the block to a new location. If this value is specified and the block cannot be enlarged without moving, the function fails, leaving the original memory block unchanged.
HEAP_ZERO_MEMORY | If the reallocation request is for a larger size, this value specifies that the additional region of memory beyond the original size be initialized to zero. The contents of the memory block up to its original size are unaffected.

lpMem
[in] Pointer to the block of memory that the function reallocates. This pointer is returned by an earlier call to the HeapAlloc or HeapReAlloc function.
dwBytes
[in] New size of the memory block, in bytes. A memory block's size can be increased or decreased by using this function.

If the heap specified by the hHeap parameter is a "non-growable" heap, dwBytes must be less than 0x7FFF8. You create a non-growable heap by calling the HeapCreate function with a nonzero value.

Return Values

If the function succeeds, the return value is a pointer to the reallocated memory block.

If the function fails and you have not specified HEAP_GENERATE_EXCEPTIONS, the return value is NULL.

If the function fails and you have specified HEAP_GENERATE_EXCEPTIONS, the function may generate the following exceptions:

Value | Meaning
STATUS_NO_MEMORY | The reallocation attempt failed for lack of available memory.
STATUS_ACCESS_VIOLATION | The reallocation attempt failed because of heap corruption or improper function parameters.

If the function fails, it calls SetLastError. An application can call GetLastError for extended error information.

Remarks

If HeapReAlloc succeeds, it allocates at least the amount of memory requested. If the actual amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual size of the reallocated block, use the HeapSize function.

If HeapReAlloc fails, the original memory is not freed, and the original handle and pointer are still valid.

To free a block of memory allocated by HeapReAlloc, use the HeapFree function.

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE value eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE value can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

Windows 95/98/Me: The heap managers are designed for memory blocks smaller than four megabytes. If you expect your memory blocks to be larger than one or two megabytes, you can avoid significant performance degradation by using the VirtualAlloc or VirtualAllocEx function instead.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapAlloc, HeapCreate, HeapDestroy, HeapFree, HeapSize, SetLastError


HeapSize

The HeapSize function returns the size, in bytes, of a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function.

DWORD HeapSize(
  HANDLE hHeap,  // handle to heap
  DWORD dwFlags, // heap size options
  LPCVOID lpMem  // pointer to memory
);

Parameters

hHeap
[in] Specifies the heap in which the memory block resides. This handle is returned by the HeapCreate or GetProcessHeap function.
dwFlags
[in] Specifies several controllable aspects of accessing the memory block. Specifying the following value overrides the corresponding value specified in the flOptions parameter when the heap was created by using the HeapCreate function.
Value Meaning
HEAP_NO_SERIALIZE Specifies that mutual exclusion will not be used while HeapSize is accessing the heap.

This value should not be specified when accessing the process heap. The system may create additional threads within the application's process, such as a CTRL+C handler, that simultaneously access the process heap.

lpMem
[in] Pointer to the memory block whose size the function will obtain. This is a pointer returned by the HeapAlloc or HeapReAlloc function.

Return Values

If the function succeeds, the return value is the size, in bytes, of the allocated memory block.

If the function fails, the return value is -1. The function does not call SetLastError. An application cannot call GetLastError for extended error information.

Remarks

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE value eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE value can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapAlloc, HeapCreate, HeapDestroy, HeapFree, HeapReAlloc, SetLastError


HeapUnlock

The HeapUnlock function releases ownership of the critical section object, or lock, that is associated with a specified heap. The HeapUnlock function reverses the action of the HeapLock function.

BOOL HeapUnlock(
  HANDLE hHeap   // handle to heap
);

Parameters

hHeap
[in] Handle to the heap to unlock.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The HeapLock function is primarily useful for preventing the allocation and release of heap memory by other threads while the calling thread uses the HeapWalk function. The HeapUnlock function is the inverse of HeapLock.

Each call to HeapLock must be matched by a corresponding call to the HeapUnlock function. Failure to call HeapUnlock will block the execution of any other threads of the calling process that attempt to access the heap.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.5 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapLock, HeapWalk


HeapValidate

The HeapValidate function attempts to validate a specified heap. The function scans all the memory blocks in the heap, and verifies that the heap control structures maintained by the heap manager are in a consistent state. You can also use the HeapValidate function to validate a single memory block within a specified heap, without checking the validity of the entire heap.

BOOL HeapValidate(
  HANDLE hHeap,  // handle to heap
  DWORD dwFlags, // heap access options
  LPCVOID lpMem  // optional pointer to memory block
);

Parameters

hHeap
[in] Handle to the heap of interest. The HeapValidate function attempts to validate this heap, or a single memory block within this heap.
dwFlags
[in] Specifies heap access during function operation. This parameter can be the following value.
Value | Meaning
HEAP_NO_SERIALIZE | Specifies that mutual exclusion is not used while the HeapValidate function accesses the heap.

lpMem
[in] Pointer to a memory block within the specified heap. This parameter may be NULL.

If this parameter is NULL, the function attempts to validate the entire heap specified by hHeap.

If this parameter is not NULL, the function attempts to validate the memory block pointed to by lpMem. It does not attempt to validate the rest of the heap.

Return Values

If the specified heap or memory block is valid, the return value is nonzero.

If the specified heap or memory block is invalid, the return value is zero. On a system set up for debugging, the HeapValidate function then displays debugging messages that describe the part of the heap or memory block that is invalid, and stops at a hard-coded breakpoint so that you can examine the system to determine the source of the invalidity. The HeapValidate function does not set the thread's last error value. There is no extended error information for this function; do not call GetLastError.

Remarks

There are heap control structures for each memory block in a heap, and for the heap as a whole. When you use the HeapValidate function to validate a complete heap, it checks all of these control structures for consistency.

When you use HeapValidate to validate a single memory block within a heap, it checks only the control structures pertaining to that element. HeapValidate can only validate allocated memory blocks. Calling HeapValidate on a freed memory block will return FALSE because there are no control structures to validate.

If you want to validate the heap elements enumerated by the HeapWalk function, you should only call HeapValidate on the elements that have PROCESS_HEAP_ENTRY_BUSY in the wFlags member of the PROCESS_HEAP_ENTRY structure. HeapValidate returns FALSE for all heap elements that do not have this bit set.

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE value eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE value can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

Validating a heap may degrade performance, especially on symmetric multiprocessing (SMP) computers. The side effects may last until the process ends.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.5 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapCreate, HeapWalk, PROCESS_HEAP_ENTRY


HeapWalk

The HeapWalk function enumerates the memory blocks in a specified heap created or manipulated by Win32 heap memory allocators such as HeapAlloc, HeapReAlloc, and HeapFree.

BOOL HeapWalk(
  HANDLE hHeap,                 // heap to enumerate
  LPPROCESS_HEAP_ENTRY lpEntry  // state information
);

Parameters

hHeap
[in] Handle to the heap whose memory blocks you wish to enumerate.
lpEntry
[in/out] Pointer to a PROCESS_HEAP_ENTRY structure that maintains state information for a particular heap enumeration.

If the HeapWalk function succeeds, returning the value TRUE, this structure's members contain information about the next memory block in the heap.

To initiate a heap enumeration, set the lpData field of the PROCESS_HEAP_ENTRY structure to NULL. To continue a particular heap enumeration, call the HeapWalk function repeatedly, with no changes to hHeap, lpEntry, or any of the members of the PROCESS_HEAP_ENTRY structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

If the heap enumeration terminates successfully by reaching the end of the heap, the function returns FALSE, and GetLastError returns the error code ERROR_NO_MORE_ITEMS.

Remarks

To initiate a heap enumeration, call HeapWalk with the lpData field of the PROCESS_HEAP_ENTRY structure pointed to by lpEntry set to NULL.

To continue a heap enumeration, call HeapWalk with the same hHeap and lpEntry values, and with the PROCESS_HEAP_ENTRY structure unchanged from the preceding call to HeapWalk. Repeat this process until you have no need for further enumeration, or until the function returns FALSE and GetLastError returns ERROR_NO_MORE_ITEMS, indicating that all of the heap's memory blocks have been enumerated.

No special call of HeapWalk is needed to terminate the heap enumeration, since no enumeration state data is maintained outside the contents of the PROCESS_HEAP_ENTRY structure.

HeapWalk can fail in a multithreaded application if the heap is not locked during the heap enumeration. Use the HeapLock and HeapUnlock functions to control heap locking during heap enumeration.

Walking a heap may degrade performance, especially on symmetric multiprocessing (SMP) computers. The side effects may last until the process ends.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information on structured exception handling with memory accesses, see Reading and Writing and Structured Exception Handling.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.5 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapAlloc, HeapReAlloc, HeapFree, HeapLock, HeapUnlock, HeapValidate, PROCESS_HEAP_ENTRY


IsBadCodePtr

The IsBadCodePtr function determines whether the calling process has read access to the memory at the specified address.

BOOL IsBadCodePtr(
  FARPROC lpfn   // memory address
);

Parameters

lpfn
[in] Pointer to an address in memory.

Return Values

If the calling process has read access to the specified memory, the return value is zero.

If the calling process does not have read access to the specified memory, the return value is nonzero. To get extended error information, call GetLastError.

If the application is compiled as a debugging version, and the process does not have read access to all bytes in the specified memory range, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, and returns a nonzero value This behavior is by design, as a debugging aid.

Remarks

IsBadCodePtr checks the read access only at the specified address and does not guarantee read access to a range of memory.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, IsBadReadPtr, IsBadStringPtr, IsBadWritePtr


IsBadReadPtr

The IsBadReadPtr function verifies that the calling process has read access to the specified range of memory.

BOOL IsBadReadPtr(
  CONST VOID *lp,  // memory address
  UINT_PTR ucb     // size of block
);

Parameters

lp
[in] Pointer to the first byte of the memory block.
ucb
[in] Specifies the size, in bytes, of the memory block. If this parameter is zero, the return value is zero.

Return Values

If the calling process has read access to all bytes in the specified memory range, the return value is zero.

If the calling process does not have read access to all bytes in the specified memory range, the return value is nonzero.

If the application is compiled as a debugging version, and the process does not have read access to all bytes in the specified memory range, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, and returns a nonzero value This behavior is by design, as a debugging aid.

Remarks

This function is typically used when working with pointers returned from third-party libraries, where you cannot determine the memory management behavior in the third-party DLL.

Threads in a process are expected to cooperate in such a way that one will not free memory that the other needs. Use of this function does not negate the need to do this. If this is not done, the application may fail in an unpredictable manner.

Dereferencing potentially invalid pointers can disable stack expansion in other threads. A thread exhausting its stack, when stack expansion has been disabled, results in the immediate termination of the parent process, with no pop-up error window or diagnostic information.

If the calling process has read access to some, but not all, of the bytes in the specified memory range, the return value is nonzero.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

MAPI: For more information, see Syntax and Limitations for Win32 Functions Useful in MAPI Development.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, IsBadCodePtr, IsBadStringPtr, IsBadWritePtr


IsBadStringPtr

The IsBadStringPtr function verifies that the calling process has read access to a range of memory pointed to by a string pointer.

BOOL IsBadStringPtr(
  LPCTSTR lpsz,      // string
  UINT_PTR ucchMax   // maximum size of string
);

Parameters

lpsz
[in] Pointer to a null-terminated string, either Unicode or ASCII.
ucchMax
[in] Specifies the maximum size, in TCHARs, of the string. The function checks for read access in all bytes up to the string's terminating null character or up to the number of bytes specified by this parameter, whichever is smaller. If this parameter is zero, the return value is zero.

Return Values

If the calling process has read access to all characters up to the string's terminating null character or up to the number of characters specified by ucchMax, the return value is zero.

If the calling process does not have read access to all characters up to the string's terminating null character or up to the number of characters specified by ucchMax, the return value is nonzero.

If the application is compiled as a debugging version, and the process does not have read access to the entire memory range specified, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, and returns a nonzero value This behavior is by design, as a debugging aid.

Remarks

This function is typically used when working with pointers returned from third-party libraries, where you cannot determine the memory management behavior in the third-party DLL.

Threads in a process are expected to cooperate in such a way that one will not free memory that the other needs. Use of this function does not negate the need to do this. If this is not done, the application may fail in an unpredictable manner.

Dereferencing potentially invalid pointers can disable stack expansion in other threads. A thread exhausting its stack, when stack expansion has been disabled, results in the immediate termination of the parent process, with no pop-up error window or diagnostic information.

If the calling process has read access to some, but not all, of the specified memory range, the return value is nonzero.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Memory Management Overview, Memory Management Functions, IsBadCodePtr, IsBadReadPtr, IsBadWritePtr


IsBadWritePtr

The IsBadWritePtr function verifies that the calling process has write access to the specified range of memory.

BOOL IsBadWritePtr(
  LPVOID lp,     // memory address
  UINT_PTR ucb   // size of memory block
);

Parameters

lp
[in] Pointer to the first byte of the memory block.
ucb
[in] Specifies the size, in bytes, of the memory block. If this parameter is zero, the return value is zero.

Return Values

If the calling process has write access to all bytes in the specified memory range, the return value is zero.

If the calling process does not have write access to all bytes in the specified memory range, the return value is nonzero.

If the application is compiled as a debugging version, and the process does not have write access to all bytes in the specified memory range, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, and returns a nonzero value This behavior is by design, as a debugging aid.

Remarks

This function is typically used when working with pointers returned from third-party libraries, where you cannot determine the memory management behavior in the third-party DLL.

Threads in a process are expected to cooperate in such a way that one will not free memory that the other needs. Use of this function does not negate the need to do this. If this is not done, the application may fail in an unpredictable manner.

Dereferencing potentially invalid pointers can disable stack expansion in other threads. A thread exhausting its stack, when stack expansion has been disabled, results in the immediate termination of the parent process, with no pop-up error window or diagnostic information.

If the calling process has write access to some, but not all, of the bytes in the specified memory range, the return value is nonzero.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has write access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

IsBadWritePtr is not multithread safe. To use it properly on a pointer shared by multiple threads, call it inside a critical region of code that allows only one thread to access the memory being checked. Use operating system–level objects such as critical sections or mutexes or the interlocked functions to create the critical region of code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, IsBadCodePtr, IsBadReadPtr


LocalAlloc

The LocalAlloc function allocates the specified number of bytes from the heap. Win32 memory management does not provide a separate local heap and global heap.

Note The local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions.

HLOCAL LocalAlloc(
  UINT uFlags,     // allocation attributes
  SIZE_T uBytes    // number of bytes to allocate
);

Parameters

uFlags
[in] Specifies how to allocate memory. If zero is specified, the default is the LMEM_FIXED value. Except for the incompatible combinations that are specifically noted, this parameter can be any combination of the following values.
Value | Meaning
LHND | Combines LMEM_MOVEABLE and LMEM_ZEROINIT.
LMEM_FIXED | Allocates fixed memory. The return value is a pointer to the memory object.
LMEM_MOVEABLE Allocates movable memory. In Win32, memory blocks are never moved in physical memory, but they can be moved within the default heap.

The return value is a handle to the memory object. To translate the handle to a pointer, use the LocalLock function.

This value cannot be combined with LMEM_FIXED.

LMEM_ZEROINIT | Initializes memory contents to zero.
LPTR | Combines LMEM_FIXED and LMEM_ZEROINIT.
NONZEROLHND | Same as LMEM_MOVEABLE.
NONZEROLPTR | Same as LMEM_FIXED.

The following values are obsolete.
Value | Meaning
LMEM_DISCARDABLE Ignored. This value is provided only for compatibility with 16-bit Windows.

In Win32, you must explicitly call the LocalDiscard function to discard a block.

This value cannot be combined with LMEM_FIXED.
LMEM_NOCOMPACT | Ignored. This value is provided only for compatibility with 16-bit Windows.
LMEM_NODISCARD | Ignored. This value is provided only for compatibility with 16-bit Windows.

uBytes
[in] Specifies the number of bytes to allocate. If this parameter is zero and the uFlags parameter specifies LMEM_MOVEABLE, the function returns a handle to a memory object that is marked as discarded.

Return Values

If the function succeeds, the return value is a handle to the newly allocated memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

If the heap does not contain sufficient free space to satisfy the request, LocalAlloc returns NULL. Because NULL is used to indicate an error, virtual address zero is never allocated. It is, therefore, easy to detect the use of a NULL pointer.

If this function succeeds, it allocates at least the amount requested. If the amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual number of bytes allocated, use the LocalSize function.

To free the memory, use the LocalFree function.

Windows 95/98/Me: The heap managers are designed for memory blocks smaller than four megabytes. If you expect your memory blocks to be larger than one or two megabytes, you can avoid significant performance degradation by using the VirtualAlloc or VirtualAllocEx function instead.

For example, see Storing an Image.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalFree, LocalLock, LocalReAlloc, LocalSize


LocalDiscard

The LocalDiscard function discards the specified local memory object. The lock count of the memory object must be zero.

Note The local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions.

HLOCAL LocalDiscard(
  HLOCAL hlocMem   // handle to local memory object
);

Parameters

hlocMem
[in] Handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Values

If the function succeeds, the return value is a handle to the local memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Although LocalDiscard discards the object's memory block, the handle to the object remains valid. A process can subsequently pass the handle to the LocalReAlloc function to allocate another local memory object identified by the same handle.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalReAlloc


LocalFlags

The LocalFlags function returns information about the specified local memory object.

Note This function is provided only for compatibility with 16-bit versions of Windows.

UINT LocalFlags(
  HLOCAL hMem   // handle to local memory object
);

Parameters

hMem
[in] Handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Values

If the function succeeds, the return value specifies the allocation values and the lock count for the memory object.

If the function fails, the return value is LMEM_INVALID_HANDLE, indicating that the local handle is not valid. To get extended error information, call GetLastError.

Remarks

The low-order byte of the low-order word of the return value contains the lock count of the object. To retrieve the lock count from the return value, use the LMEM_LOCKCOUNT mask with the bitwise AND (&) operator. The lock count of memory objects allocated with LMEM_FIXED is always zero.

The high-order byte of the low-order word of the return value indicates the allocation values of the memory object. It can be zero or a combination of the following values.

Value | Description
LMEM_DISCARDABLE | Ignored. This value is provided only for compatibility with 16-bit Windows. In Win32, you must explicitly call the LocalDiscard function to discard a block.
LMEM_DISCARDED | The object's memory block has been discarded.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalFlags, LocalAlloc, LocalDiscard, LocalLock, LocalReAlloc, LocalUnlock


LocalFree

The LocalFree function frees the specified local memory object and invalidates its handle.

Note The local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions.

HLOCAL LocalFree(
  HLOCAL hMem   // handle to local memory object
);

Parameters

hMem
[in] Handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Values

If the function succeeds, the return value is NULL.

If the function fails, the return value is equal to a handle to the local memory object. To get extended error information, call GetLastError.

Remarks

If the process tries to examine or modify the memory after it has been freed, heap corruption may occur or an access violation exception (EXCEPTION_ACCESS_VIOLATION) may be generated.

If the hMem parameter is NULL, LocalFree ignores the parameter and returns NULL.

The LocalFree function will free a locked memory object. A locked memory object has a lock count greater than zero. The LocalLock function locks a local memory object and increments the lock count by one. The LocalUnlock function unlocks it and decrements the lock count by one. To get the lock count of a local memory object, use the LocalFlags function.

If an application is running under a debug version of the system, LocalFree will issue a message that tells you that a locked object is being freed. If you are debugging the application, LocalFree will enter a breakpoint just before freeing a locked object. This allows you to verify the intended behavior, then continue execution.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalFree, LocalAlloc, LocalFlags, LocalLock, LocalReAlloc, LocalUnlock


LocalHandle

The LocalHandle function retrieves the handle associated with the specified pointer to a local memory object.

Note The local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions.

HLOCAL LocalHandle(
  LPCVOID pMem   // pointer to local memory object
);

Parameters

pMem
[in] Pointer to the first byte of the local memory object. This pointer is returned by the LocalLock function.

Return Values

If the function succeeds, the return value is a handle to the specified local memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

When the LocalAlloc function allocates a local memory object with LMEM_MOVEABLE, it returns a handle to the object. The LocalLock function converts this handle into a pointer to the object's memory block, and LocalHandle converts the pointer back into a handle.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalLock


LocalLock

The LocalLock function locks a local memory object and returns a pointer to the first byte of the object's memory block.

Note The local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions.

LPVOID LocalLock(
  HLOCAL hMem   // handle to local memory object
);

Parameters

hMem
[in] Handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Values

If the function succeeds, the return value is a pointer to the first byte of the memory block.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, LocalLock increments the count by one, and the LocalUnlock function decrements the count by one. For each call that a process makes to LocalLock for an object, it must eventually call LocalUnlock. Locked memory will not be moved or discarded unless the memory object is reallocated by using the LocalReAlloc function. The memory block of a locked memory object remains locked in memory until its lock count is decremented to zero, at which time it can be moved or discarded.

Memory objects allocated with LMEM_FIXED always have a lock count of zero. For these objects, the value of the returned pointer is equal to the value of the specified handle.

If the specified memory block has been discarded or if the memory block has a zero-byte size, this function returns NULL.

Discarded objects always have a lock count of zero.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalFlags, LocalReAlloc, LocalUnlock


LocalReAlloc

The LocalReAlloc function changes the size or the attributes of a specified local memory object. The size can increase or decrease.

Note The local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions.

HLOCAL LocalReAlloc(
  HLOCAL hMem,    // handle to local memory object
  SIZE_T uBytes,  // new block size
  UINT uFlags     // how to reallocate object
);

Parameters

hMem
[in] Handle to the local memory object to be reallocated. This handle is returned by either the LocalAlloc or LocalReAlloc function.
uBytes
[in] New size, in bytes, of the memory block. If uFlags specifies LMEM_MODIFY, this parameter is ignored.
uFlags
[in] Specifies how to reallocate the local memory object. If LMEM_MODIFY is specified, this parameter modifies the attributes of the memory object, and the uBytes parameter is ignored. Otherwise, this parameter controls the reallocation of the memory object.

You can combine LMEM_MODIFY with the following value.
Value Meaning
LMEM_DISCARDABLE Ignored. This value is provided only for compatibility with 16-bit Windows.

In Win32, you must explicitly call the LocalDiscard function to discard a block.

If this parameter does not specify LMEM_MODIFY, this parameter can be any combination of the following values.
Value | Meaning
LMEM_MOVEABLE Allocates movable memory. Otherwise, the memory will only be reallocated in place.

The return value is a handle to the memory object. To convert the handle to a pointer, use the LocalLock function.

LMEM_NOCOMPACT | Ignored. This value is provided only for compatibility with 16-bit Windows.
LMEM_ZEROINIT | Causes the additional memory contents to be initialized to zero if the memory object is growing in size.

Return Values

If the function succeeds, the return value is a handle to the reallocated memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

If LocalReAlloc fails, the original memory is not freed, and the original handle and pointer are still valid.

If LocalReAlloc reallocates a fixed object, the value of the handle returned is the address of the first byte of the memory block. To access the memory, a process can simply cast the return value to a pointer.

Windows 95/98/Me: The heap managers are designed for memory blocks smaller than four megabytes. If you expect your memory blocks to be larger than one or two megabytes, you can avoid significant performance degradation by using the VirtualAlloc or VirtualAllocEx function instead.

For example, see Example of Owner-Drawn Menu Items.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalFree, LocalLock


LocalSize

The LocalSize function returns the current size, in bytes, of the specified local memory object.

Note The local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions.

UINT LocalSize(
  HLOCAL  hMem   // handle to local memory object
);

Parameters

hMem
[in] Handle to the local memory object. This handle is returned by the LocalAlloc, LocalReAlloc, or LocalHandle function.

Return Values

If the function succeeds, the return value is the size, in bytes, of the specified local memory object. If the specified handle is not valid or if the object has been discarded, the return value is zero. To get extended error information, call GetLastError.

Remarks

The size of a memory block may be larger than the size requested when the memory was allocated.

To verify that the specified object's memory block has not been discarded, call the LocalFlags function before calling LocalSize.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalFlags, LocalHandle, LocalReAlloc


LocalUnlock

The LocalUnlock function decrements the lock count associated with a memory object that was allocated with LMEM_MOVEABLE. This function has no effect on memory objects allocated with LMEM_FIXED.

Note The local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions.

BOOL LocalUnlock(
  HLOCAL hMem   // handle to local memory object
);

Parameters

hMem
[in] Handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Values

If the memory object is still locked after decrementing the lock count, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If GetLastError returns NO_ERROR, the memory object is unlocked.

Remarks

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, the LocalLock function increments the count by one, and LocalUnlock decrements the count by one. For each call that a process makes to LocalLock for an object, it must eventually call LocalUnlock. Locked memory will not be moved or discarded unless the memory object is reallocated by using the LocalReAlloc function. The memory block of a locked memory object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded.

If the memory object is already unlocked, LocalUnlock returns FALSE and GetLastError reports ERROR_NOT_LOCKED. Memory objects allocated with LMEM_FIXED always have a lock count of zero and cause the ERROR_NOT_LOCKED error.

A process should not rely on the return value to determine the number of times it must subsequently call LocalUnlock for the memory block.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalFlags, LocalLock, LocalReAlloc


MapUserPhysicalPages

The MapUserPhysicalPages function maps previously allocated physical memory pages at the specified address within an Address Windowing Extensions (AWE) region.

To perform "batch" mapping and unmapping of multiple regions, use the MapUserPhysicalPagesScatter function.

BOOL MapUserPhysicalPages(
  PVOID lpAddress,         // starting address of region
  ULONG_PTR NumberOfPages, // size of physical memory
  PULONG_PTR UserPfnArray  // array of page frame numbers
);

Parameters

lpAddress
[in] Pointer to the starting address of the region of memory to remap. The value of lpAddress must be within the address range returned by the VirtualAlloc function when the AWE region was allocated.
NumberOfPages
[in] Specifies the size, in pages, of the physical memory (and virtual address space) to establish translations for. The virtual address range is contiguous starting at lpAddress. The physical frames are specified by the UserPfnArray. The total number of pages cannot extend from the starting address beyond the end of the range specified in AllocateUserPhysicalPages.
UserPfnArray
[in] Specifies the address of an array of physical page frame numbers. These frames will be mapped by the argument lpAddress upon return from this function. The size of the memory allocated should be at least NumberOfPages times the size of the data type ULONG_PTR.

Do not attempt to modify this buffer. It contains operating system data, corruption of which could be catastrophic. There is no information in it that is useful to your application.

Specifying NULL for this parameter results in the specified address range being unmapped. (The specified physical pages are not freed. You must call FreeUserPhysicalPages to free them.)

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE and no mapping (partial or otherwise) will have been done. To get extended error information, call GetLastError.

Remarks

Any number of physical memory pages can be specified, provided the memory would not extend outside the virtual address space allocated by VirtualAlloc. Any existing address maps are automatically overwritten with the new translations, and the old translations are unmapped.

You cannot map physical memory pages outside the range specified in AllocateUserPhysicalPages.

Note The physical pages are unmapped but they are not freed. You must call FreeUserPhysicalPages to free the physical pages.

Physical pages can reside at any physical address. You should make no assumptions about the contiguity of the physical pages.

To simply unmap the current address range, specify NULL as the physical memory page array parameter. Any currently mapped pages are unmapped, but are not freed. You must call FreeUserPhysicalPages to free the physical pages.

In a multiprocessor environment, this function maintains hardware translation buffer coherence. Upon return from this function, all threads on all processors are guaranteed to see the correct mapping.

For example, see AWE Example.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Address Windowing Extensions, AllocateUserPhysicalPages, FreeUserPhysicalPages, MapUserPhysicalPagesScatter


MapUserPhysicalPagesScatter

The MapUserPhysicalPagesScatter function maps previously allocated physical memory pages at the specified address within an Address Windowing Extensions (AWE) region.

Unlike MapUserPhysicalPages, MapUserPhysicalPagesScatter allows "batch" mapping and unmapping of multiple regions.

BOOL MapUserPhysicalPagesScatter(
  PVOID *VirtualAddresses,  // starting address of region
  ULONG_PTR NumberOfPages,  // size of physical memory
  PULONG_PTR PageArray      // array of values
);

Parameters

VirtualAddresses
[in] Pointer to an array of starting addresses of the regions of memory to remap. Each entry in VirtualAddresses must be within the address range that the VirtualAlloc function returned when the AWE region was allocated. The value in NumberOfPages indicates the size of the array. Note that entries can be from multiple AWE regions.
NumberOfPages
[in] Specifies the size, in pages, of the physical memory (and virtual address space) to establish translations for. The array at VirtualAddresses specifies the virtual address range.
PageArray
[in] A non-NULL pointer to an array of values.

If this parameter is NULL, then every address in the VirtualAddresses array will be unmapped.

Otherwise, the array is used to indicate how each corresponding page in VirtualAddresses should be treated. A zero indicates that the corresponding entry in VirtualAddresses should be unmapped; any nonzero value that it has should be mapped.

The value in NumberOfPages indicates the size of the array.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE and the function does no mapping or unmapping (partial or otherwise). To get extended error information, call GetLastError.

Remarks

You can specify any number of physical memory pages, provided the memory would not extend outside the virtual address space allocated by VirtualAlloc. Any existing address maps are automatically overwritten with the new translations, and the old translations are unmapped.

You cannot map physical memory pages outside the range specified in AllocateUserPhysicalPages.

Note The physical pages may be unmapped but they are not freed. You must call FreeUserPhysicalPages to free the physical pages.

Physical pages can reside at any physical address. You should make no assumptions about the contiguity of the physical pages.

In a multiprocessor environment, this function maintains coherence of the hardware translation buffer. Upon return from this function, all threads on all processors are guaranteed to see the correct mapping.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Address Windowing Extensions, AllocateUserPhysicalPages, FreeUserPhysicalPages, MapUserPhysicalPages


MoveMemory

The MoveMemory function moves a block of memory from one location to another.

VOID MoveMemory (
  PVOID Destination,   // move destination
  CONST VOID *Source,  // block to move
  SIZE_T Length        // size of block to move
);

Parameters

Destination
[in] Pointer to the starting address of the destination of the move.
Source
[in] Pointer to the starting address of the block of memory to move.
Length
[in] Specifies the size, in bytes, of the block of memory to move.

Return Values

This function has no return value.

Remarks

The source and destination blocks may overlap.

MAPI: For more information, see Syntax and Limitations for Win32 Functions Useful in MAPI Development.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.

See Also

Memory Management Overview, Memory Management Functions, CopyMemory, FillMemory, ZeroMemory


ResetWriteWatch

The ResetWriteWatch function resets the write-tracking state for a region of virtual memory. Subsequent calls to the GetWriteWatch function will only report pages that have been written to since the reset operation.

UINT ResetWriteWatch(
  LPVOID lpBaseAddress,     // base address
  SIZE_T dwRegionSize       // size of memory region
);

Parameters

lpBaseAddress
[in] Pointer to the base address of the memory region for which to reset the write-tracking state. This address must be in a memory region that was allocated by the VirtualAlloc function with MEM_WRITE_WATCH.
dwRegionSize
[in] Specifies the size, in bytes, of the memory region for which to reset the write-tracking information.

Return Values

If the function succeeds, the return value is zero.

If the function fails, the return value is a nonzero value.

Remarks

The ResetWriteWatch function can be useful to an application such as a garbage collector. The application calls the GetWriteWatch function to retrieve the list of written pages and then writes to those pages as part of its cleanup operation. Then the garbage collector calls ResetWriteWatch to remove the write-tracking records caused by its cleanup.

You can also reset the write-tracking state of a memory region by specifying WRITE_WATCH_FLAG_RESET when you call GetWriteWatch.

If you use ResetWriteWatch, you must ensure that no threads write to the region during the interval between the GetWriteWatch and ResetWriteWatch calls. Otherwise, there may be written pages that you fail to detect.

Requirements

Windows NT/2000 or later: Unsupported .
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetWriteWatch, VirtualAlloc


VirtualAlloc

The VirtualAlloc function reserves or commits a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero, unless MEM_RESET is specified.

To allocate memory in the address space of another process, use the VirtualAllocEx function.

LPVOID VirtualAlloc(
  LPVOID lpAddress,        // region to reserve or commit
  SIZE_T dwSize,           // size of region
  DWORD flAllocationType,  // type of allocation
  DWORD flProtect          // type of access protection
);

Parameters

lpAddress
[in] Specifies the desired starting address of the region to allocate. If the memory is being reserved, the specified address is rounded down to the next 64-kilobyte boundary. If the memory is already reserved and is being committed, the address is rounded down to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function. If this parameter is NULL, the system determines where to allocate the region.
dwSize
[in] Specifies the size, in bytes, of the region. If the lpAddress parameter is NULL, this value is rounded up to the next page boundary. Otherwise, the allocated pages include all pages containing one or more bytes in the range from lpAddress to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.
flAllocationType
[in] Specifies the type of allocation. This parameter must contain one of the following values: MEM_COMMIT, MEM_RESET, or MEM_RESERVE. All other values can be used as indicated in the following table.
Value | Meaning
MEM_COMMIT Allocates physical storage in memory or in the paging file on disk for the specified region of memory pages. The function initializes the memory to zero.

An attempt to commit a memory page that is already committed does not cause the function to fail. This means that you can commit a range of pages without determining the current commitment state of each page.

If a memory page is not yet reserved, setting this value causes the function to both reserve and commit the memory page.
MEM_PHYSICAL Allocates physical memory with read-write access. This value is solely for use with Address Windowing Extensions (AWE) memory.

This value must be used with MEM_RESERVE and no other values.

MEM_RESERVE Reserves a range of the process's virtual address space without allocating any actual physical storage in memory or in the paging file on disk.

Other memory allocation functions such as malloc and LocalAlloc, cannot use a reserved range of memory until it is released.

You can commit reserved memory pages in subsequent calls to the VirtualAlloc function.
MEM_RESET Windows NT/2000 or later: Specifies that the data in the memory range specified by lpAddress and dwSize is no longer of interest. The pages should not be read from or written to the paging file. However, the memory block will be used again later, so it should not be decommitted. This value cannot be used with any other value.

Using this value does not guarantee that the range operated on with MEM_RESET will contain zeroes. If you want the range to contain zeroes, decommit the memory and then recommit it.

When you specify MEM_RESET, the VirtualAlloc function ignores the value of fProtect. However, you must still set fProtect to a valid protection value, such as PAGE_NOACCESS.

VirtualAlloc returns an error if you use MEM_RESET and the range of memory is mapped to a file. A shared view is only acceptable if it is mapped to a paging file.

MEM_TOP_DOWN | Windows NT/2000 or later: Allocates memory at the highest possible address.
MEM_WRITE_WATCH Windows 98/Me: Causes the system to track pages that are written to in the allocated region. If you specify this value, you must also specify MEM_RESERVE.

To retrieve the addresses of the pages that have been written to since the region was allocated or the write-tracking state was reset, call the GetWriteWatch function. To reset the write-tracking state, call GetWriteWatch or ResetWriteWatch. The write-tracking feature remains enabled for the memory region until the region is freed.

flProtect
[in] Specifies the type of access protection. If the pages are being committed, you can specify any one of the following value, along with PAGE_GUARD and PAGE_NOCACHE as needed.
Value | Meaning
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.
PAGE_EXECUTE | Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write access to the committed region of pages.
PAGE_GUARD Windows NT/2000 or later: Pages in the region become guard pages. Any attempt to read from or write to a guard page causes the system to raise a STATUS_GUARD_PAGE exception and turn off the guard page status. Guard pages thus act as a one-shot access alarm.

PAGE_GUARD is a page protection modifier. An application uses it with one of the other page protection modifiers, with one exception: it cannot be used with PAGE_NOACCESS. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.

If a guard page exception occurs during a system service, the service typically returns a failure status indicator.

Windows 95/98/Me: To simulate this behavior, use PAGE_NOACCESS.

PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be specified as "no cache." This is not recommended for general usage. It is useful for device drivers; for example, mapping a video frame buffer with no caching. This value is a page protection modifier, and it is only valid when used with one of the page protections other than PAGE_NOACCESS.

Return Values

If the function succeeds, the return value is the base address of the allocated region of pages.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

VirtualAlloc can perform the following operations:

  • Commit a region of pages reserved by a previous call to the VirtualAlloc function.
  • Reserve a region of free pages.
  • Reserve and commit a region of free pages.

You can use VirtualAlloc to reserve a block of pages and then make additional calls to VirtualAlloc to commit individual pages from the reserved block. This enables a process to reserve a range of its virtual address space without consuming physical storage until it is needed.

Each page in the process's virtual address space is in one of the following states.

State | Meaning
Free | The page is not committed or reserved and is not accessible to the process. VirtualAlloc can reserve, or simultaneously reserve and commit, a free page.
Reserved | The range of addresses cannot be used by other allocation functions, but the page is not accessible and has no physical storage associated with it. VirtualAlloc can commit a reserved page, but it cannot reserve it a second time. The VirtualFree function can release a reserved page, making it a free page.
Committed | Physical storage is allocated for the page, and access is controlled by a protection code. The system initializes and loads each committed page into physical memory only at the first attempt to read or write to that page. When the process terminates, the system releases the storage for committed pages. VirtualAlloc can commit an already committed page. This means that you can commit a range of pages, regardless of whether they have already been committed, and the function will not fail. VirtualFree can decommit a committed page, releasing the page's storage, or it can simultaneously decommit and release a committed page.

If the lpAddress parameter is not NULL, the function uses the lpAddress and dwSize parameters to compute the region of pages to be allocated. The current state of the entire range of pages must be compatible with the type of allocation specified by the flAllocationType parameter. Otherwise, the function fails and none of the pages are allocated. This compatibility requirement does not preclude committing an already committed page; see the preceding list.

Windows NT/2000 or later: The PAGE_GUARD protection modifier establishes guard pages. Guard pages act as one-shot access alarms. For more information, see Creating Guard Pages.

Address Windowing Extensions (AWE): The VirtualAlloc function can be used to reserve an AWE region of memory within the virtual address space of a specified process. This region of memory can then be used to map physical pages into and out of virtual memory as required by the application.

The MEM_PHYSICAL and MEM_RESERVE values must be set in the AllocationType parameter. The MEM_COMMIT value must not be set.

The page protection must be set to PAGE_READWRITE.

The VirtualFree function can be used on an AWE region of memory – in this case, it will invalidate any physical page mappings in the region when freeing the address space. However, the physical pages themselves are not deleted, and the application can subsequently use them. The application must explicitly call FreeUserPhysicalPages to free the physical pages. On process termination, all resources are automatically cleaned up.

For example, see Reserving and Committing Memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Address Windowing Extensions (AWE), AllocateUserPhysicalPages, FreeUserPhysicalPages, GetWriteWatch, HeapAlloc, MapUserPhysicalPages, MapUserPhysicalPagesScatter, ResetWriteWatch, VirtualAllocEx, VirtualFree, VirtualLock, VirtualProtect, VirtualQuery


VirtualAllocEx

The VirtualAllocEx function reserves, commits, or reserves and commits a region of memory within the virtual address space of a specified process. The function initializes the memory it allocates to zero, unless MEM_RESET is used.

LPVOID VirtualAllocEx(
  HANDLE hProcess,          // process to allocate memory
  LPVOID lpAddress,         // desired starting address
  SIZE_T dwSize,            // size of region to allocate
  DWORD flAllocationType,   // type of allocation
  DWORD flProtect           // type of access protection
);

Parameters

hProcess
[in] Handle to a process. The function allocates memory within the virtual address space of this process.

You must have PROCESS_VM_OPERATION access to the process. If you do not, the function fails.

lpAddress
[in] Pointer that specifies a desired starting address for the region of pages that you want to allocate.

If you are reserving memory, the function rounds this address down to the nearest 64-kilobyte boundary.

If you are committing memory that is already reserved, the function rounds this address down to the nearest page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.

If lpAddress is NULL, the function determines where to allocate the region.

dwSize
[in] Specifies the size, in bytes, of the region of memory to allocate.

If lpAddress is NULL, the function rounds dwSize up to the next page boundary.

If lpAddress is not NULL, the function allocates all pages that contain one or more bytes in the range from lpAddress to (lpAddress+dwSize). This means, for example, that a 2-byte range that straddles a page boundary causes the function to allocate both pages.

flAllocationType
[in] Specifies the type of memory allocation. This parameter must contain one of the following values: MEM_COMMIT, MEM_RESET, or MEM_RESERVE. All other values can be used as indicated in the following table.
Value | Meaning
MEM_COMMIT Allocates physical storage in memory or in the paging file on disk for the specified region of memory pages. The function initializes the memory to zero.

An attempt to commit a memory page that is already committed does not cause the function to fail. This means that you can commit a range of pages without first determining the current commitment state of each page.

If a memory page is not yet reserved, setting this value causes the function to both reserve and commit the memory page.
MEM_PHYSICAL Allocates physical memory with read-write access. This value is solely for use with Address Windowing Extensions (AWE) memory.

This value must be used with MEM_RESERVE and no other values.

MEM_RESERVE Reserves a range of the process's virtual address space without allocating any actual physical storage in memory or in the paging file on disk.

Other memory allocation functions, such as malloc and LocalAlloc, cannot use a reserved range of memory until it is released.

You can commit reserved memory pages in subsequent calls to the VirtualAllocEx function.

MEM_RESET Specifies that the data in the memory range specified by lpAddress and dwSize is no longer of interest. The pages should not be read from or written to the paging file. However, the memory block will be used again later, so it should not be decommitted. This value cannot be used with any other value.

Using this value does not guarantee that the range operated on with MEM_RESET will contain zeroes. If you want the range to contain zeroes, decommit the memory and then recommit it.

When you use MEM_RESET, the VirtualAllocEx function ignores the value of fProtect. However, you must still set fProtect to a valid protection value, such as PAGE_NOACCESS.

VirtualAllocEx returns an error if you use MEM_RESET and the range of memory is mapped to a file. A shared view is only acceptable if it is mapped to a paging file.
MEM_TOP_DOWN | The function allocates memory at the highest possible address.

flProtect
[in] Specifies access protection for the region of pages you are allocating. You can specify one of the following values, along with the PAGE_GUARD and PAGE_NOCACHE protection values, as desired.
Value | Meaning
PAGE_READONLY | Enables read permission to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only permission and execute permission, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write permission to the committed region of pages.
PAGE_EXECUTE | Enables execute permission to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read permission to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write permission to the committed region of pages.
PAGE_GUARD Pages in the region become guard pages. Any attempt to read from or write to a guard page causes the system to raise a STATUS_GUARD_PAGE exception and turn off the guard page status. Guard pages thus act as a one-shot access alarm.

This value is a page protection modifier. An application uses it with one of the other page protection values, with one exception: it cannot be used with PAGE_NOACCESS. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.

If a guard page exception occurs during a system service, the service typically returns a failure status indicator.

PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be specified as "no cache." This is not recommended for general usage. It is useful for device drivers; for example, mapping a video frame buffer with no caching. This value is a page protection modifier, and it is only valid when used with one of the page protections other than PAGE_NOACCESS.

Return Values

If the function succeeds, the return value is the base address of the allocated region of pages.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The VirtualAllocEx function can perform the following operations:

  • Commit a region of pages reserved by a previous call to the VirtualAllocEx function.
  • Reserve a region of free pages.
  • Reserve and commit a region of free pages.

You can use VirtualAllocEx to reserve a block of pages and then make additional calls to VirtualAllocEx to commit individual pages from the reserved block. This lets you reserve a range of a process's virtual address space without consuming physical storage until it is needed.

Each page of memory in a process's virtual address space is in one of the following states.

State | Meaning
Free | The page is not committed or reserved and is not accessible to the process. The VirtualAllocEx function can reserve, or simultaneously reserve and commit, a free page.
Reserved | The page is reserved. The range of addresses cannot be used by other allocation functions, but the page is not accessible and has no physical storage associated with it. The VirtualAllocEx function can commit a reserved page, but it cannot reserve it a second time. You can use the VirtualFreeEx function to release a reserved page in a specified process, making it a free page.
Committed | Physical storage is allocated for the page, and access is controlled by a protection code. The system initializes and loads each committed page into physical memory only at the first attempt to read or write to that page. When the process terminates, the system releases the storage for committed pages. The VirtualAllocEx function can commit an already committed page. This means that you can commit a range of pages, regardless of whether they have already been committed, and the function will not fail. You can use the VirtualFreeEx function to decommit a committed page in a specified process, or to simultaneously decommit and free a committed page.

If the lpAddress parameter is not NULL, the function uses the lpAddress and dwSize parameters to compute the region of pages to be allocated. The current state of the entire range of pages must be compatible with the type of allocation specified by the flAllocationType parameter. Otherwise, the function fails and none of the pages is allocated. This compatibility requirement does not preclude committing an already committed page; see the preceding list.

The PAGE_GUARD protection modifier establishes guard pages. Guard pages act as one-shot access alarms. For more information, see Creating Guard Pages.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapAlloc, VirtualFreeEx, VirtualLock, VirtualProtect, VirtualQuery


VirtualFree

The VirtualFree function releases, decommits, or releases and decommits a region of pages within the virtual address space of the calling process.

To free memory allocated in another process by the VirtualAllocEx function, use the VirtualFreeEx function.

BOOL VirtualFree(
  LPVOID lpAddress,   // address of region
  SIZE_T dwSize,      // size of region
  DWORD dwFreeType    // operation type
);

Parameters

lpAddress
[in] Pointer to the base address of the region of pages to be freed. If the dwFreeType parameter includes MEM_RELEASE, this parameter must be the base address returned by the VirtualAlloc function when the region of pages was reserved.
dwSize
[in] Specifies the size, in bytes, of the region to be freed. If the dwFreeType parameter includes MEM_RELEASE, this parameter must be zero. Otherwise, the region of affected pages includes all pages containing one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes both pages to be freed.
dwFreeType
[in] Specifies the type of free operation. This parameter can be one of the following values.
Value | Meaning
MEM_DECOMMIT Decommits the specified region of committed pages.

An attempt to decommit an uncommitted page will not cause the function to fail. This means that a range of committed or uncommitted pages can be decommitted without having to worry about a failure.
MEM_RELEASE | Releases the specified region of reserved pages. If this value is specified, the dwSize parameter must be zero, or the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

VirtualFree can perform one of the following operations:

  • Decommit a region of committed or uncommitted pages.
  • Release a region of reserved pages.
  • Decommit and release a region of committed or uncommitted pages.

Pages that have been released are free pages available for subsequent allocation operations. Attempting to read from or write to a free page results in an access violation exception.

VirtualFree can decommit an uncommitted page; this means that a range of committed or uncommitted pages can be decommitted without having to worry about a failure. Decommitting a page releases its physical storage, either in memory or in the paging file on disk. If a page is decommitted but not released, its state changes to reserved, and it can be committed again by a subsequent call to VirtualAlloc. Attempting to read from or write to a reserved page results in an access violation exception.

The current state of the entire range of pages must be compatible with the type of free operation specified by the dwFreeType parameter. Otherwise, the function fails and no pages are released or decommitted.

For example, see Reserving and Committing Memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, VirtualFreeEx


VirtualFreeEx

The VirtualFreeEx function releases, decommits, or releases and decommits a region of memory within the virtual address space of a specified process.

BOOL VirtualFreeEx(
  HANDLE hProcess,   // handle to process
  LPVOID lpAddress,  // starting address of memory region
  SIZE_T dwSize,     // size of memory region
  DWORD dwFreeType   // operation type
);

Parameters

hProcess
[in] Handle to a process. The function frees memory within the virtual address space of this process.

You must have PROCESS_VM_OPERATION access to this process. If you do not, the function fails.

lpAddress
[in] Pointer to the starting address of the region of memory to free.

If the MEM_RELEASE value is used in the dwFreeType parameter, lpAddress must be the base address returned by the VirtualAllocEx function when the region was reserved.

dwSize
[in] Specifies the size, in bytes, of the region of memory to free.

If the MEM_RELEASE value is used in the dwFreeType parameter, dwSize must be zero. The function frees the entire region that was reserved in the initial allocation call to VirtualAllocEx.

If the MEM_DECOMMIT value is used, the function decommits all memory pages that contain one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means, for example, that a 2-byte region of memory that straddles a page boundary causes both pages to be decommitted.

The function decommits the entire region that was reserved by VirtualAllocEx. If the following three conditions are met:

  • MEM_DECOMMIT is used
  • lpAddress is the base address returned by the VirtualAllocEx function when the region was reserved
  • dwSize is zero

The entire region the enters the reserved state.

dwFreeType
[in] Specifies the type of free operation. This parameter can be one of the following values.
Value Meaning
MEM_DECOMMIT The function decommits the specified region of pages. The pages enter the reserved state.

The function does not fail if you attempt to decommit an uncommitted page. This means that you can decommit a range of pages without first determining their current commitment state.
MEM_RELEASE The function releases the specified region of pages. The pages enter the free state.

If you specify this value, dwSize must be zero, and lpAddress must point to the base address returned by the VirtualAllocEx function when the region was reserved. The function fails if either of these conditions is not met.
If any pages in the region are currently committed, the function first decommits and then releases them.

The function does not fail if you attempt to release pages that are in different states, some reserved and some committed. This means that you can release a range of pages without first determining their current commitment state.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Each page of memory in a process's virtual address space is in one of the following states.

State Meaning
Free The page is neither committed nor reserved. The page is not accessible to the process. Attempting to read from or write to a free page results in an access violation exception.

You can use the VirtualFreeEx function to put reserved or committed memory pages into the free state.

Reserved The page is reserved. The range of addresses cannot be used by other allocation functions. The page is not accessible and has no physical storage associated with it. Attempting to read from or write to a free page results in an access violation exception.

You can use the VirtualFreeEx function to put committed memory pages into the reserved state, and to put reserved memory pages into the free state.

Committed The page is committed. Physical storage in memory or in the paging file on disk is allocated for the page, and access is controlled by a protection code.

The system initializes and loads each committed page into physical memory only at the first attempt to read from or write to that page.

When a process terminates, the system releases all storage for committed pages.

You can use the VirtualAllocEx function to put committed memory pages into either the reserved or free state.

The VirtualFreeEx function can perform the following operations:

  • Decommit a region of committed or uncommitted pages. After this operation, the pages are in the reserved state.
  • Release a region of reserved pages. After this operation, the pages are in the free state.
  • Decommit and release a region of committed or uncommitted pages. After this operation, the pages are in the free state.

The VirtualFreeEx function can decommit a range of pages that are in different states, some committed and some uncommitted. This means that you can decommit a range of pages without first determining the current commitment state of each page. Decommitting a page releases its physical storage, either in memory or in the paging file on disk.

If a page is decommitted but not released, its state changes to reserved. You can subsequently call VirtualAllocEx to commit it, or VirtualFreeEx to release it. Attempting to read from or write to a reserved page results in an access violation exception.

The VirtualFreeEx function can release a range of pages that are in different states, some reserved and some committed. This means that you can release a range of pages without first determining the current commitment state of each page. The entire range of pages originally reserved by the VirtualAllocEx function must be released at the same time.

If a page is released, its state changes to free, and it is available for subsequent allocation operations. Once memory is released or decommitted, you can never refer to the memory again. Any information that may have been in that memory is gone forever. Attempting to read from or write to a free page results in an access violation exception. If you require information, do not decommit or free memory containing that information.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, VirtualAllocEx


VirtualLock

The VirtualLock function locks the specified region of the process's virtual address space into physical memory, ensuring that subsequent access to the region will not incur a page fault.

BOOL VirtualLock(
  LPVOID lpAddress,   // first byte in range
  SIZE_T dwSize       // number of bytes in range
);

Parameters

lpAddress
[in] Pointer to the base address of the region of pages to be locked.
dwSize
[in] Specifies the size, in bytes, of the region to be locked. The region of affected pages includes all pages that contain one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes both pages to be locked.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

All pages in the specified region must be committed. Memory protected with PAGE_NOACCESS cannot be locked.

Locking pages into memory may degrade the performance of the system by reducing the available RAM and forcing the system to swap out other critical pages to the paging file. By default, a process can lock a maximum of 30 pages. The default limit is intentionally small to avoid severe performance degradation. Applications that need to lock larger numbers of pages must first call the SetProcessWorkingSetSize function to increase their minimum and maximum working set sizes. The maximum number of pages that a process can lock is equal to the number of pages in its minimum working set minus a small overhead.

Pages that a process has locked remain in physical memory until the process unlocks them or terminates.

To unlock a region of locked pages, use the VirtualUnlock function. Locked pages are automatically unlocked when the process terminates.

This function is not like the GlobalLock or LocalLock function in that it does not increment a lock count and translate a handle into a pointer. There is no lock count for virtual pages, so multiple calls to the VirtualUnlock function are never required to unlock a region of pages.

Windows 95/98/Me: The VirtualLock function is implemented as a stub that has no effect and always returns a nonzero value.

For example, see Creating Guard Pages.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, SetProcessWorkingSetSize, VirtualUnlock


VirtualProtect

The VirtualProtect function changes the access protection on a region of committed pages in the virtual address space of the calling process.

To change the access protection of any process, use the VirtualProtectEx function.

BOOL VirtualProtect(
  LPVOID lpAddress,       // region of committed pages
  SIZE_T dwSize,          // size of the region
  DWORD flNewProtect,     // desired access protection
  PDWORD lpflOldProtect   // old protection
);

Parameters

lpAddress
[in] Pointer to the base address of the region of pages whose access protection attributes are to be changed.

All pages in the specified region must be within the same reserved region allocated when calling the VirtualAlloc or VirtualAllocEx function using MEM_RESERVE. The pages cannot span adjacent reserved regions that were allocated by separate calls to VirtualAlloc or VirtualAllocEx using MEM_RESERVE.

dwSize
[in] Specifies the size, in bytes, of the region whose access protection attributes are to be changed. The region of affected pages includes all pages containing one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes the protection attributes of both pages to be changed.
flNewProtect
[in] Specifies the new access protection. You can specify any one of the following value, along with the PAGE_GUARD and PAGE_NOCACHE values, as necessary.
Value | Meaning
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.
PAGE_WRITECOPY | Windows NT/2000 or later: Gives copy-on-write access to the committed region of pages.
PAGE_EXECUTE | Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write access to the committed region of pages.
PAGE_EXECUTE_WRITECOPY | Enables execute, read, and write access to the committed region of pages. The pages are shared read-on-write and copy-on-write.
PAGE_GUARD Windows NT/2000 or later: Pages in the region become guard pages. Any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE exception and turn off the guard page status. Guard pages thus act as a one-shot access alarm.

PAGE_GUARD is a page protection modifier. An application uses it with one of the other page protection modifiers, with one exception: it cannot be used with PAGE_NOACCESS. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.

If a guard page exception occurs during a system service, the service typically returns a failure status indicator.

Windows 95/98/Me: To simulate this behavior, use PAGE_NOACCESS.

PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be specified as "no cache." This is not recommended for general usage. It is useful for device drivers; for example, mapping a video frame buffer with no caching. This value is a page protection modifier; it is only valid when used with one of the page protections other than PAGE_NOACCESS.

lpflOldProtect
[out] Pointer to a variable that receives the previous access protection value of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

You can set the access protection value on committed pages only. If the state of any page in the specified region is not committed, the function fails and returns without modifying the access protection of any pages in the specified region.

The VirtualProtect function changes the access protection of memory in the calling process, and the VirtualProtectEx function changes the access protection of memory in a specified process.

Windows NT/2000 or later: The PAGE_GUARD protection modifier establishes guard pages. Guard pages act as one-shot access alarms. For more information, see Creating Guard Pages.

Windows 95/98/Me: You cannot use VirtualProtect on any memory region located in the shared virtual address space (from 0x80000000 through 0xBFFFFFFF).

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, VirtualAlloc, VirtualProtectEx


VirtualProtectEx

The VirtualProtectEx function changes the access protection on a region of committed pages in the virtual address space of a specified process.

BOOL VirtualProtectEx(
  HANDLE hProcess,        // handle to process
  LPVOID lpAddress,       // region of committed pages
  SIZE_T dwSize,          // size of region
  DWORD flNewProtect,     // desired access protection
  PDWORD lpflOldProtect   // old protection
);

Parameters

hProcess
[in] Handle to the process whose memory protection is to be changed. The handle must have PROCESS_VM_OPERATION access. For more information on PROCESS_VM_OPERATION, see OpenProcess.
lpAddress
[in] Pointer to the base address of the region of pages whose access protection attributes are to be changed.

All pages in the specified region must be within the same reserved region allocated when calling the VirtualAlloc or VirtualAllocEx function using MEM_RESERVE. The pages cannot span adjacent reserved regions that were allocated by separate calls to VirtualAlloc or VirtualAllocEx using MEM_RESERVE.

dwSize
[in] Specifies the size, in bytes, of the region whose access protection attributes are changed. The region of affected pages includes all pages containing one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes the protection attributes of both pages to be changed.
flNewProtect
[in] Specifies the new access protection. You can specify any one of the following values, along with the PAGE_GUARD and PAGE_NOCACHE values, as desired.
Value | Meaning
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.
PAGE_WRITECOPY | Windows NT/2000 or later: Gives copy-on-write access to the committed region of pages.
PAGE_EXECUTE | Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write access to the committed region of pages.
PAGE_EXECUTE_WRITECOPY | Enables execute, read, and write access to the committed region of pages. The pages are shared read-on-write and copy-on-write.
PAGE_GUARD Windows NT/2000 or later: Pages in the region become guard pages. Any attempt to read from or write to a guard page causes the system to raise a STATUS_GUARD_PAGE exception, and turn off the guard page status. Guard pages thus act as a one-shot access alarm.

PAGE_GUARD is a page protection modifier. An application uses it with one of the other page protection modifiers, with one exception: it cannot be used with PAGE_NOACCESS. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.

If a guard page exception occurs during a system service, the service typically returns a failure status indicator.

Windows 95/98/Me: To simulate this behavior, use PAGE_NOACCESS.

PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be set to "no cache." This is not recommended for general usage. It is useful for device drivers; for example, mapping a video frame buffer with no caching. This value is a page protection modifier; it is only valid when used with one of the page protections other than PAGE_NOACCESS.

lpflOldProtect
[out] Pointer to a variable that receives the previous access protection of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The access protection value can be set only on committed pages. If the state of any page in the specified region is not committed, the function fails and returns without modifying the access protection of any pages in the specified region.

VirtualProtectEx is identical to the VirtualProtect function except that it changes the access protection of memory in a specified process.

Windows NT/2000 or later: The PAGE_GUARD protection modifier establishes guard pages. Guard pages act as one-shot access alarms. For more information, see Creating Guard Pages.

Windows 95/98/Me: You cannot use VirtualProtectEx on any memory region located in the shared virtual address space (from 0x80000000 through 0xBFFFFFFF).

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, VirtualAlloc, VirtualProtect, VirtualQueryEx


VirtualQuery

The VirtualQuery function provides information about a range of pages in the virtual address space of the calling process.

To obtain information about a range of pages in the address space of another process, use the VirtualQueryEx function.

DWORD VirtualQuery(
  LPCVOID lpAddress,                   // address of region
  PMEMORY_BASIC_INFORMATION lpBuffer,  // information buffer
  SIZE_T dwLength                      // size of buffer
);

Parameters

lpAddress
[in] Pointer to the base address of the region of pages to be queried. This value is rounded down to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.
lpBuffer
[out] Pointer to a MEMORY_BASIC_INFORMATION structure in which information about the specified page range is returned.
dwLength
[in] Specifies the size, in bytes, of the buffer pointed to by the lpBuffer parameter.

Return Values

The return value is the actual number of bytes returned in the information buffer.

Remarks

VirtualQuery provides information about a region of consecutive pages beginning at a specified address that share the following attributes:

  • The state of all pages is the same with MEM_COMMIT, MEM_RESERVE, MEM_FREE, MEM_PRIVATE, MEM_MAPPED, or MEM_IMAGE.
  • If the initial page is not free, all pages in the region are part of the same initial allocation of pages reserved by a call to the VirtualAlloc function.
  • The access of all pages is the same with PAGE_READONLY, PAGE_READWRITE, PAGE_NOACCESS, PAGE_WRITECOPY, PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY, PAGE_GUARD, or PAGE_NOCACHE.

The function determines the attributes of the first page in the region and then scans subsequent pages until it scans the entire range of pages or until it encounters a page with a nonmatching set of attributes. The function returns the attributes and the size, in bytes, of the region of pages with matching attributes. For example, if there is a 40 megabyte (MB) region of free memory, and VirtualQuery is called on a page that is 10 MB into the region, the function will obtain a state of MEM_FREE and a size of 30 MB.

This function reports on a region of pages in the memory of the calling process, and the VirtualQueryEx function reports on a region of pages in the memory of a specified process.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetSystemInfo, MEMORY_BASIC_INFORMATION, VirtualQueryEx


VirtualQueryEx

The VirtualQueryEx function provides information about a range of pages within the virtual address space of a specified process.

DWORD VirtualQueryEx(
  HANDLE hProcess,                     // handle to process
  LPCVOID lpAddress,                   // address of region
  PMEMORY_BASIC_INFORMATION lpBuffer,  // information buffer
  SIZE_T dwLength                      // size of buffer
);

Parameters

hProcess
[in] Handle to the process whose memory information is queried. The handle must have been opened with PROCESS_QUERY_INFORMATION, which enables using the handle to read information from the process object.
lpAddress
[in] Pointer to the base address of the region of pages to be queried. This value is rounded down to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.
lpBuffer
[out] Pointer to a MEMORY_BASIC_INFORMATION structure in which information about the specified page range is returned.
dwLength
[in] Specifies the size, in bytes, of the buffer pointed to by the lpBuffer parameter.

Return Values

The return value is the actual number of bytes returned in the information buffer.

Remarks

VirtualQueryEx provides information about a region of consecutive pages beginning at a specified address that share the following attributes:

  • The state of all pages is the same with MEM_COMMIT, MEM_RESERVE, MEM_FREE, MEM_PRIVATE, MEM_MAPPED, or MEM_IMAGE.
  • If the initial page is not free, all pages in the region are part of the same initial allocation of pages reserved by a call to the VirtualAllocEx function.
  • The access of all pages is the same with PAGE_READONLY, PAGE_READWRITE, PAGE_NOACCESS, PAGE_WRITECOPY, PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY, PAGE_GUARD, or PAGE_NOCACHE.

The VirtualQueryEx function determines the attributes of the first page in the region and then scans subsequent pages until it scans the entire range of pages, or until it encounters a page with a nonmatching set of attributes. The function returns the attributes and the size, in bytes, of the region of pages with matching attributes. For example, if there is a 40 megabyte (MB) region of free memory, and VirtualQueryEx is called on a page that is 10 MB into the region, the function will obtain a state of MEM_FREE and a size of 30 MB.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetSystemInfo, MEMORY_BASIC_INFORMATION, VirtualAllocEx, VirtualProtectEx


VirtualUnlock

The VirtualUnlock function unlocks a specified range of pages in the virtual address space of a process, enabling the system to swap the pages out to the paging file if necessary.

BOOL VirtualUnlock(
  LPVOID lpAddress,   // first byte in range
  SIZE_T dwSize       // number of bytes in range
);

Parameters

lpAddress
[in] Pointer to the base address of the region of pages to be unlocked.
dwSize
[in] Specifies the size, in bytes, of the region being unlocked. The region of affected pages includes all pages containing one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes both pages to be unlocked.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

For the function to succeed, the range specified need not match a range passed to a previous call to the VirtualLock function, but all pages in the range must be locked.

Windows NT/2000 or later: Calling VirtualUnlock on a range of memory that is not locked releases the pages from the process's working set.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, VirtualLock


ZeroMemory

The ZeroMemory function fills a block of memory with zeros.

VOID ZeroMemory(
  PVOID Destination,  // memory block
  SIZE_T Length       // size of memory block
);

Parameters

Destination
[in] Pointer to the starting address of the block of memory to fill with zeros.
Length
[in] Size, in bytes, of the block of memory to fill with zeros.

Return Values

This function has no return value.

Remarks

MAPI: For more information, see Syntax and Limitations for Win32 Functions Useful in MAPI Development.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.

See Also

Memory Management Overview, Memory Management Functions, CopyMemory, FillMemory, MoveMemory


Memory Management Structures

The following structures are used with memory management.

MEMORY_BASIC_INFORMATION
MEMORYSTATUS
MEMORYSTATUSEX
PROCESS_HEAP_ENTRY


MEMORY_BASIC_INFORMATION

The MEMORY_BASIC_INFORMATION structure contains information about a range of pages in the virtual address space of a process. The VirtualQuery and VirtualQueryEx functions use this structure.

typedef struct _MEMORY_BASIC_INFORMATION {
  PVOID BaseAddress;
  PVOID AllocationBase;
  DWORD AllocationProtect;
  SIZE_T RegionSize;
  DWORD State;
  DWORD Protect;
  DWORD Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;

Members

BaseAddress
Pointer to the base address of the region of pages.
AllocationBase
Pointer to the base address of a range of pages allocated by the VirtualAlloc function. The page pointed to by the BaseAddress member is contained within this allocation range.
AllocationProtect
Specifies the access protection given when the region was initially allocated. This member can be one of the following values, along with PAGE_GUARD and PAGE_NOCACHE.
Value | Meaning
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.
PAGE_WRITECOPY | Windows NT/2000 or later: Gives copy-on-write access to the committed region of pages.
PAGE_EXECUTE | Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write access to the committed region of pages.
PAGE_EXECUTE_WRITECOPY | Enables execute, read, and write access to the committed region of pages. The pages are shared read-on-write and copy-on-write.
PAGE_GUARD Windows NT/2000 or later: Protects the page with the underlying page protection. However, access to the region causes a "guard page entered" condition to be raised in the subject process. This value is a page protection modifier, only valid when used with one of the page protections other than PAGE_NOACCESS.

Windows 95/98/Me: To simulate this behavior, use PAGE_NOACCESS.

PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be set to no cache. This is not recommended for general usage. It is useful for device drivers; for example, mapping a video frame buffer with no caching. This value is a page protection modifier, only valid when used with one of the page protections other than PAGE_NOACCESS.

RegionSize
Specifies the size, in bytes, of the region beginning at the base address in which all pages have identical attributes.
State
Specifies the state of the pages in the region. One of the following states is indicated.
State | Meaning
MEM_COMMIT | Indicates committed pages for which physical storage has been allocated, either in memory or in the paging file on disk.
MEM_FREE | Indicates free pages not accessible to the calling process and available to be allocated. For free pages, the information in the AllocationBase, AllocationProtect, Protect, and Type members is undefined.
MEM_RESERVE | Indicates reserved pages where a range of the process's virtual address space is reserved without any physical storage being allocated. For reserved pages, the information in the Protect member is undefined.

Protect
Specifies the access protection of the pages in the region. One of the values listed for the AllocationProtect member is specified.
Type
Specifies the type of pages in the region. The following types are defined.
Type | Meaning
MEM_IMAGE | Indicates that the memory pages within the region are mapped into the view of an image section.
MEM_MAPPED | Indicates that the memory pages within the region are mapped into the view of a section.
MEM_PRIVATE | Indicates that the memory pages within the region are private (that is, not shared by other processes).

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Memory Management Overview, Memory Management Structures, VirtualAlloc, VirtualQuery, VirtualQueryEx


MEMORYSTATUS

The MEMORYSTATUS structure contains information about the current state of both physical and virtual memory. The GlobalMemoryStatus function stores information in a MEMORYSTATUS structure.

typedef struct _MEMORYSTATUS {
  DWORD dwLength;
  DWORD dwMemoryLoad;
  SIZE_T dwTotalPhys;
  SIZE_T dwAvailPhys;
  SIZE_T dwTotalPageFile;
  SIZE_T dwAvailPageFile;
  SIZE_T dwTotalVirtual;
  SIZE_T dwAvailVirtual;
} MEMORYSTATUS, *LPMEMORYSTATUS;

Members

dwLength
Size of the MEMORYSTATUS data structure, in bytes. You do not need to set this member before calling the GlobalMemoryStatus function; the function sets it.
dwMemoryLoad
Windows NT 4.0 and earlier: The percentage of approximately the last 1000 pages of physical memory that is in use.

Windows 2000 and later: The approximate percentage of total physical memory that is in use.

dwTotalPhys
Total size of physical memory, in bytes.
dwAvailPhys
Size of physical memory available, in bytes.
dwTotalPageFile
Size of the committed memory limit, in bytes.
dwAvailPageFile
Size of available memory to commit, in bytes.
dwTotalVirtual
Total size of the user mode portion of the virtual address space of the calling process, in bytes.
dwAvailVirtual
Size of unreserved and uncommitted memory in the user mode portion of the virtual address space of the calling process, in bytes.

Remarks

MEMORYSTATUS reflects the state of memory at the time of the call. It reflects the size of the paging file at that time. The operating system can enlarge the paging file up to the maximum size set by the administrator.

On computers with more than 4 GB of memory, the MEMORYSTATUS structure can return incorrect information. Windows 2000 reports a value of -1 to indicate an overflow. Earlier versions of Windows NT report a value that is the real amount of memory, modulo 4 GB. If your application is at risk for this behavior, use the GlobalMemoryStatusEx function instead of the GlobalMemoryStatus function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.

See Also

Memory Management Overview, Memory Management Structures, GlobalMemoryStatus, GlobalMemoryStatusEx


MEMORYSTATUSEX

The MEMORYSTATUSEX structure contains information about the current state of both physical and virtual memory, including extended memory. The GlobalMemoryStatusEx function stores information in a MEMORYSTATUSEX structure.

typedef struct _MEMORYSTATUSEX {
  DWORD dwLength;
  DWORD dwMemoryLoad;
  DWORDLONG ullTotalPhys;
  DWORDLONG ullAvailPhys;
  DWORDLONG ullTotalPageFile;
  DWORDLONG ullAvailPageFile;
  DWORDLONG ullTotalVirtual;
  DWORDLONG ullAvailVirtual;
  DWORDLONG ullAvailExtendedVirtual;
} MEMORYSTATUSEX, *LPMEMORYSTATUSEX;

Members

dwLength
Size of the MEMORYSTATUSEX data structure, in bytes. You must set this member before calling the GlobalMemoryStatusEx function.
dwMemoryLoad
Number between 0 and 100 that gives a general idea of current memory utilization, in which 0 indicates no memory use and 100 indicates full memory use.
ullTotalPhys
Total size of physical memory, in bytes.
ullAvailPhys
Size of physical memory available, in bytes.
ullTotalPageFile
Size of the committed memory limit, in bytes.
ullAvailPageFile
Size of available memory to commit, in bytes.
ullTotalVirtual
Total size of the user mode portion of the virtual address space of the calling process, in bytes.
ullAvailVirtual
Size of unreserved and uncommitted memory in the user mode portion of the virtual address space of the calling process, in bytes.
ullAvailExtendedVirtual
Size of unreserved and uncommitted memory in the extended portion of the virtual address space of the calling process, in bytes.

Remarks

MEMORYSTATUSEX reflects the state of memory at the time of the call. It reflects the size of the paging file at that time. The operating system can enlarge the paging file up to the maximum size set by the administrator.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.

See Also

Memory Management Overview, Memory Management Structures, GlobalMemoryStatus, GlobalMemoryStatusEx, MEMORYSTATUS


PROCESS_HEAP_ENTRY

The PROCESS_HEAP_ENTRY structure contains information about a heap element. The HeapWalk function uses a PROCESS_HEAP_ENTRY structure to enumerate the elements of a heap.

typedef struct _PROCESS_HEAP_ENTRY {
  PVOID lpData;
  DWORD cbData;
  BYTE cbOverhead;
  BYTE iRegionIndex;
  WORD wFlags;
  union {
      struct {
          HANDLE hMem;
          DWORD dwReserved[ 3 ];
      } Block;
      struct {
          DWORD dwCommittedSize;
          DWORD dwUnCommittedSize;
          LPVOID lpFirstBlock;
          LPVOID lpLastBlock;
      } Region;
  };
} PROCESS_HEAP_ENTRY, *LPPROCESS_HEAP_ENTRY;

Members

lpData
Pointer to the data portion of the heap element.

To initiate a HeapWalk heap enumeration, set lpData to NULL.

If PROCESS_HEAP_REGION is used in the wFlags member, lpData points to the first virtual address used by the region.

If PROCESS_HEAP_UNCOMMITTED_RANGE is used in wFlags, lpData points to the beginning of the range of uncommitted memory.

cbData
Specifies the size, in bytes, of the data portion of the heap element.

If PROCESS_HEAP_REGION is used in wFlags, cbData specifies the total size, in bytes, of the address space that is reserved for this region.

If PROCESS_HEAP_UNCOMMITTED_RANGE is used in wFlags, cbData specifies the size, in bytes, of the range of uncommitted memory.

cbOverhead
Specifies the size, in bytes, of the data used by the system to maintain information about the heap element. These overhead bytes are in addition to the cbData bytes of the data portion of the heap element.

If PROCESS_HEAP_REGION is used in wFlags, cbOverhead specifies the size, in bytes, of the heap control structures that describe the region.

If PROCESS_HEAP_UNCOMMITTED_RANGE is used in wFlags, cbOverhead specifies the size, in bytes, of the control structures that describe this uncommitted range.

iRegionIndex
Handle to the heap region that contains the heap element. A heap consists of one or more regions of virtual memory, each with a unique region index.

In the first heap entry returned for most heap regions, HeapWalk uses the PROCESS_HEAP_REGION in the wFlags member. When this value is used, the members of the Region structure contain additional information about the region.

The HeapAlloc function sometimes uses the VirtualAlloc function to allocate large blocks from a growable heap. The heap manager treats such a large block allocation as a separate region with a unique region index. HeapWalk does not use PROCESS_HEAP_REGION in the heap entry returned for a large block region, so the members of the Region structure are not valid. You can use the VirtualQuery function to get additional information about a large block region.

wFlags
Specifies properties of the heap element. Some values affect the meaning of other members of this PROCESS_HEAP_ENTRY data structure. The following values are defined.
Value | Meaning
PROCESS_HEAP_REGION The heap element is located at the beginning of a region of contiguous virtual memory in use by the heap.

The lpData member of the structure points to the first virtual address used by the region; the cbData member specifies the total size, in bytes, of the address space that is reserved for this region; and the cbOverhead member specifies the size, in bytes, of the heap control structures that describe the region.

The Region structure becomes valid. The dwCommittedSize, dwUnCommittedSize, lpFirstBlock, and lpLastBlock members of the structure contain additional information about the region.
PROCESS_HEAP_UNCOMMITTED_RANGE The heap element is located in a range of uncommitted memory within the heap region.

The lpData member points to the beginning of the range of uncommitted memory; the cbData member specifies the size, in bytes, of the range of uncommitted memory; and the cbOverhead member specifies the size, in bytes, of the control structures that describe this uncommitted range.
PROCESS_HEAP_ENTRY_BUSY The heap element is an allocated block.

If PROCESS_HEAP_ENTRY_MOVEABLE is also specified, the Block structure becomes valid. The hMem member of the Block structure contains a handle to the allocated, moveable memory block.

PROCESS_HEAP_ENTRY_MOVEABLE This value must be used with PROCESS_HEAP_ENTRY_BUSY, indicating that the heap element is an allocated block.

The block was allocated with LMEM_MOVEABLE or GMEM_MOVEABLE, and the Block structure becomes valid. The hMem member of the Block structure contains a handle to the allocated, moveable memory block.

PROCESS_HEAP_ENTRY_DDESHARE | This value must be used with PROCESS_HEAP_ENTRY_BUSY, indicating that the heap element is an allocated block.

Block
This structure is valid only if both the PROCESS_HEAP_ENTRY_BUSY and PROCESS_HEAP_ENTRY_MOVEABLE are specified in wFlags.

The members of the Block structure are as follows.
Member | Description
hMem | Contains a handle to the allocated, moveable memory block.
dwReserved | Reserved; not used.

Region
This structure is valid only if the wFlags member specifies PROCESS_HEAP_REGION.

The members of the Region structure are as follows.
Member | Description
dwCommittedSize Specifies the number of bytes in the heap region that are currently committed as free memory blocks, busy memory blocks, or heap control structures.

This is an optional field that is set to zero if the number of committed bytes is not available.
dwUnCommittedSize Specifies the number of bytes in the heap region that are currently uncommitted.

This is an optional field that is set to zero if the number of uncommitted bytes is not available.

lpFirstBlock | Pointer to the first valid memory block in this heap region.
lpLastBlock | Pointer to the first invalid memory block in this heap region.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.5 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.

See Also

Memory Management Overview, Memory Management Structures, GlobalAlloc, HeapAlloc, HeapWalk, VirtualAlloc, VirtualQuery


File Mapping

The following topics describe file mapping and how to use the file-mapping functions:

  • About File Mapping
  • Using File Mapping
  • File Mapping Reference


About File Mapping

File mapping is the association of a file's contents with a portion of the virtual address space of a process. The system creates a file-mapping object to maintain this association. A file view is the portion of virtual address space that the process uses to access the file's contents. Processes read from and write to the file view using pointers, just as they would with dynamically allocated memory. Processes can also manipulate the file view with the virtual memory function VirtualProtect.

The file-mapping functions allow a process to create file-mapping objects and file views to easily access and share data. The following illustration shows the relationship between the file on disk, a file-mapping object, and a file view.

The file on disk can be any file that you want to map into memory, or it can be the system pagefile.

The file-mapping object can consist of all or only part of the file. It is backed by the file on disk. This means that when the system swaps out pages of the file-mapping object, any changes made to the file-mapping object are written to the file. When the pages of the file-mapping object are swapped back in, they are restored from the file.

A file view can consist of all or only part of the file-mapping object. A process manipulates the file through the file views. A process can create multiple views for a file-mapping object.

  • Windows NT/2000 or later: The file views created by each process reside in the virtual address space of that process.
  • Windows 95/98/Me: All file views reside in the shared address space. The shared address space exists in the range between 2 and 3 gigabytes in the virtual address space for each process. It contains the 16-bit heap and shared system DLLs, as well as file views.

When multiple processes use the same file-mapping object to create views for a local file, the data is coherent. That is, the views contain identical copies of the file on disk. The file cannot reside on a remote computer if you want to share memory between multiple processes.


Advantages of File Mapping

File mapping provides two major advantages:

  • Shared memory
  • Faster and easier file access

File mapping allows two or more applications to share memory. On Windows, applications cannot share memory by any other means.

File mapping allows a process to access files more quickly and easily by using a pointer to a file view. Using a pointer improves efficiency because the file resides on disk, but the file view resides in memory. File mapping allows the process to use both random input and output (I/O) and sequential I/O. It also allows the process to efficiently work with a large data file, such as a database, without having to map the whole file into memory. When the process needs data from a portion of the file other than what is in the current file view, it can unmap the current file view, then create a new file view.


Creating a File-Mapping Object

The first step in mapping a file is to open the file by calling the CreateFile function. To ensure that other processes cannot write to the portion of the file that is mapped, you should open the file with exclusive access. In addition, the file handle should remain open until the process no longer needs the file-mapping object. An easy way to obtain exclusive access is to specify zero in the fdwShareMode parameter of CreateFile. The handle returned by CreateFile is used by the CreateFileMapping function to create a file-mapping object.

The CreateFileMapping function returns a handle to the file-mapping object. This handle will be used when creating a file view so that you can access the shared memory. When you call CreateFileMapping, you specify an object name, the number of bytes to be mapped from the file, and the read/write permission for the mapped memory. The first process that calls CreateFileMapping creates the file-mapping object. Processes calling CreateFileMapping for an existing object receive a handle to the existing object. You can tell whether or not a successful call to CreateFileMapping created or opened the file-mapping object by calling the GetLastError function. GetLastError returns NO_ERROR to the creating process and ERROR_ALREADY_EXISTS to subsequent processes.

The CreateFileMapping function fails if the access flags conflict with those specified when the CreateFile function opened the file. For example, to read and write to the file:

  • Specify the GENERIC_READ and GENERIC_WRITE values in the fdwAccess parameter of CreateFile.
  • Specify the PAGE_READWRITE value in the fdwProtect parameter of CreateFileMapping.

Creating a file-mapping object does not commit physical memory, it only reserves it.

File-mapping Size

The size of the file-mapping object is independent of the size of the file being mapped. However, if the file-mapping object is larger than the file, the system expands the file before CreateFileMapping returns. If the file-mapping object is smaller than the file, the system maps only the specified number of bytes from the file.

The dwMaximumSizeHigh and dwMaximumSizeLow parameters of CreateFileMapping allow you to specify the number of bytes to be mapped from the file:

  • Windows 95/98/Me: The dwMaximumSizeHigh parameter is not used because it is not supported by the 32-bit file system. The value should be zero.

    When you do not want the size of the file to change (for example, when mapping read-only files), call CreateFileMapping and specify zero for both dwMaximumSizeHigh and dwMaximumSizeLow. Doing this creates a file-mapping object exactly the same size as the file. Otherwise, you must calculate or estimate the size of the finished file because file-mapping objects are static in size; once created, their size cannot increase or decrease. An attempt to map a file with a length of zero in this manner fails with an error code of ERROR_FILE_INVALID. Programs should test for files with a length of zero and reject such files:

  • Windows NT/2000 or later: The size of a file-mapping object backed by a named file is limited by disk space. The size of a file view is limited to the largest available contiguous block of unreserved virtual memory. This is at most 2 GB minus the virtual memory already reserved by the process.
  • Windows 95/98/Me: The size of a file-mapping object backed by a named file is also limited by disk space. The size of a file view is limited to the largest available contiguous block of unreserved virtual memory in the shared address space. This is at most 1 GB minus the virtual memory in use by other processes, such as 16-bit Windows-based applications or Win32-based applications using file mapping.

The size of the file-mapping object you select controls how far into the file you can "see" with memory mapping. If you create a file-mapping object of 500 Kb, you have access only to the first 500 Kb of the file, regardless of the size of the file. Since it costs you no system resources to create a larger file-mapping object, create one the size of the file (set the dwMaximumSizeHigh and dwMaximumSizeLow parameters of CreateFileMapping both to zero) even if you do not expect to view the entire file. The cost in system resources comes in creating the views and accessing them.

If you want to view a portion of the file that does not start at the beginning of the file, you must create a file-mapping object. This object is the size of the portion of the file you want to view plus the offset into the file.


Creating a File View

To map the data from a file to the virtual memory of a process, you must create a view of the file. The MapViewOfFile and MapViewOfFileEx functions use the file-mapping object handle returned by CreateFileMapping to create a view of the file or a portion of the file in the process's virtual address space. These functions fail if the access flags conflict with those specified when CreateFileMapping created the file-mapping object.

The MapViewOfFile function returns a pointer to the file view. By dereferencing a pointer in the range of addresses specified in MapViewOfFile, an application can read data from the file and write data to the file. Writing to the file view results in changes to the file-mapping object. The actual writing to the file on disk is handled by the system. Data is not actually transferred at the time the file-mapping object is written to. Instead, much of the file input and output (I/O) is cached to improve general system performance. Applications can override this behavior by calling the FlushViewOfFile function to force the system to perform disk transactions immediately.

The MapViewOfFileEx function works exactly like the MapViewOfFile function except that it allows a process to specify the base address of the view of the file in the process's virtual address space in the lpvBase parameter. If there is not enough space at the specified address, the call fails. Therefore, if you must map a file to the same address in multiple processes, the processes should negotiate an appropriate address:

  • Windows NT/2000 or later: The lpvBase parameter must be an integral multiple of the system memory allocation granularity or the call fails. To obtain the system's memory allocation granularity, use the GetSystemInfo function, which fills in the members of a SYSTEM_INFO structure.
  • Windows 95/98/Me: The address is rounded down to the nearest integral multiple of the system's memory allocation granularity. For subsequent file views, if the address specified does not match the address to which the system mapped the file view, MapViewOfFileEx fails.

An application can create multiple file views from the same file-mapping object. A file view can be a different size than the file-mapping object from which it is derived, but it must be smaller than the file-mapping object. The offset specified by the dwOffsetHigh and dwOffsetLow parameters of MapViewOfFile must be a multiple of the allocation granularity of the system.


Two Examples of File Mapping

If you want to view a portion of the file that does not start at the beginning of the file, you must create a file-mapping object. This object is the size of the portion of the file you want to view plus the offset into the file. For example, if you want to view the 1 kilobyte (1K) that begins 131,072 bytes (128K) into the file, you must create a file-mapping object of at least 132,096 bytes (129K) in size. The view would start 131,072 bytes (128K) into the file and extend for at least 1,024 bytes. This example assumes a file allocation granularity of 64K.

File allocation granularity affects where a map view can start. A map view must start at an offset into the file that is a multiple of the file allocation granularity. So the data you want to view may be the file offset modulo the allocation granularity into the view. The size of the view would be the offset of the data modulo the allocation granularity, plus the size of the data you want to examine.

If you wanted to examine 1K of data offset 138,240 bytes (135K) into the file, assuming that the GetSystemInfo function indicates an allocation granularity of 64K, you would:

  1. Create a file-mapping object of at least 139,264 bytes (136K) in size.
  2. Create a file view that starts at a file offset that is the largest multiple of the file allocation granularity less than the offset you require. In this case, the file view would start at offset 131,072 (128K) into the file. The view would be 139264 bytes (136K) minus 131,072 bytes (128K), or 8,192 bytes (8K), in size.
  3. Create a pointer offset 7K into the view to access the 1K in which you were interested.

If the data you want straddles a file allocation granularity boundary, you could make the view larger than the file allocation granularity. This would avoid breaking the data into pieces.

The following program illustrates the second example above.

/* filemap.c,

   This program demonstrates file mapping, especially how to align a view
   with the system file allocation granularity.

#include <windows.h>

#define BUFFSIZE 1024 // the size of the memory to examine at any one time

#define FILE_MAP_START 138240 // starting point within the file of the
 // data to examine (135K)

/* The test file. The code below creates the file and populates it, so there is
   no need to supply it in advance. */

char * lpcTheFile = "fmtest.txt"; // the file to be manipulated

int main(void)
{
  HANDLE hMapFile;              // handle for the test file's memory-mapped region
  HANDLE hFile;                 // the file handle
  BOOL bFlag;                   // a result holder
  DWORD dBytesWritten;          // number of bytes written
  DWORD dwFileSize;             // temporary storage for file sizes
  DWORD dwFileMapSize;          // size of the file mapping
  DWORD dwMapViewSize;          // the size of the view
  DWORD dwFileMapStart;         // where in the file to start the file map view
  DWORD dwSysGran;              // system allocation granularity
  SYSTEM_INFO SysInfo;          // system information; used to get the granularity
  LPVOID lpMapAddress;          // pointer to the base address of the memory-mapped region
  char * pData;                 // pointer to the data
  int i;                        // loop counter
  int iData;                    // the first int of the data, if everything goes right
  int iViewDelta;               // the offset into the view where the data shows up
  int iRet;                     // the return value

  // Create the test file. Open it "Create Always" to overwrite any
  // existing file. The data is re-created below.
  hFile = CreateFile(lpcTheFile, GENERIC_READ | GENERIC_WRITE, 0, NULL,
                     CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

  if (hFile == INVALID_HANDLE_VALUE) {
    printf("hFile is NULL\n");
    printf("Target file is %s\n", lpcTheFile);
    return 4;
  }

  // Get the system allocation granularity.
  GetSystemInfo(&SysInfo);
  dwSysGran = SysInfo.dwAllocationGranularity;

  // Now calculate a few variables. Calculate the file offsets as
  // 64-bit values, and then get the low-order 32 bits for the
  // function calls.

  // To calculate where to start the file mapping, round down the
  // offset of the data into the file to the nearest multiple of the
  // system allocation granularity.
  dwFileMapStart = (FILE_MAP_START / dwSysGran) * dwSysGran;
  printf ("The file map view starts at %ld bytes into the file.\n",
          dwFileMapStart);

  // Calculate the size of the file mapping view.
  dwMapViewSize = (FILE_MAP_START % dwSysGran) + BUFFSIZE;
  printf ("The file map view is %ld bytes large.\n", dwMapViewSize);

  // How large will the file-mapping object be?
  dwFileMapSize = FILE_MAP_START + BUFFSIZE;
  printf ("The file-mapping object is %ld bytes large.\n", dwFileMapSize);

  // The data of interest isn't at the beginning of the
  // view, so determine how far into the view to set the pointer.
  iViewDelta = FILE_MAP_START - dwFileMapStart;
  printf ("The data is %d bytes into the view.\n", iViewDelta);

  // Now write a file with data suitable for experimentation. This
  // provides unique int (4-byte) locations in the file for easy visual
  // inspection. Note that this code does not check for storage medium overflow
  // or other errors, which production code should do. Because an int is 4 bytes,
  // the value at the pointer to the data should be one quarter of the
  // desired offset into the file.
  for (i=0;i<2*dwSysGran;i++) {
    WriteFile (hFile, &i, sizeof (i), &dBytesWritten, NULL);
  }

  // Let the user know that the resulting file is more than large enough
  // for the experiment.
  dwFileSize = GetFileSize(hFile,  NULL);
  printf("hFile size: %10d\n", dwFileSize);

  // Create a file-mapping object for the file.
  hMapFile = CreateFileMapping( hFile, // current file handle
                                NULL, // default security
                                PAGE_READWRITE, // read/write permission
                                0,  // size of mapping object, high
                                dwFileMapSize, // size of mapping object, low
                                NULL); // name of mapping object

  if (hMapFile == NULL) {
    printf("hMapFile is NULL: last error: %d\n", GetLastError() );
    return (2);
  }

  // Map the view and test the results.

  lpMapAddress = MapViewOfFile(hMapFile, // handle to mapping object
                               FILE_MAP_ALL_ACCESS, // read/write permission
                               0, // high-order 32 bits of file offset
                               dwFileMapStart, // low-order 32 bits of file offset
                               dwMapViewSize); // number of bytes to map
  if (lpMapAddress == NULL) {
    printf("lpMapAddress is NULL: last error: %d\n", GetLastError());
    return 3;
  }

  // Calculate the pointer to the data.
  pData = (char *) lpMapAddress + iViewDelta;

//    dump((char *)pData, BUFFSIZE);

  // Extract the data, an int. Cast the pointer pData from a "pointer to
  // char" to a "pointer to int" to get the whole thing.
  iData = *(int *)pData;

  printf ("The value at the pointer is %d,\nwhich %s one quarter of the desired file offset.\n",
          iData,
          iData*4 == FILE_MAP_START ? "is" : "is not");

  // Close the file-mapping object and the open file.

  bFlag = CloseHandle(hMapFile); // close the file-mapping object

  if(!bFlag) {
    printf("\nOops! Error # %ld occurred closing the mapping object!",
           GetLastError());
  }

  bFlag = CloseHandle(hFile);   // close the file itself

  if(!bFlag) {
    printf("\nOops! Error # %ld occurred closing the file!",
           GetLastError());
  }

  return 0;

}


Closing the File-Mapping Object

When a process has finished with the file-mapping object, it should destroy all file views in its address space by using the UnmapViewOfFile function for each file view. This function invalidates the pointer to the process's virtual address space. If any of the pages of the file view have changed since the view was mapped, the system writes the changed pages of the file to disk using caching. To commit the data to disk immediately, call the FlushViewOfFile function before unmapping the file view.

You must call the CloseHandle function to first close the file-mapping object and then close the file on disk. These calls to CloseHandle succeed even when there are file views that are still open. However, leaving file views mapped causes memory leaks.


Sharing Files and Memory

File mapping can be used to share a file or memory between two or more processes. To share a file or memory, all of the processes must use the name or the handle of the same file-mapping object.

To share a file, the first process creates or opens a file by using the CreateFile function. Next, it creates a file-mapping object by using the CreateFileMapping function, specifying the file handle and a name for the file-mapping object. The names of event, semaphore, mutex, waitable timer, job, and file-mapping objects share the same name space. Therefore, the CreateFileMapping and OpenFileMapping functions fail if they specify a name that is in use by an object of another type.

To share memory that is not associated with a file, a process must use the CreateFileMapping function and specify INVALID_HANDLE_VALUE as the hfile parameter instead of an existing file handle. The corresponding file-mapping object accesses memory backed by the system paging file. You must specify a size greater than zero when you specify an hfile of INVALID_HANDLE_VALUE in a call to CreateFileMapping.

The easiest way for other processes to obtain a handle of the file-mapping object created by the first process is to use the OpenFileMapping function and specify the object's name. This is referred to as named shared memory. If the file-mapping object does not have a name, the process must obtain a handle to it through inheritance or duplication. For more information on inheritance and duplication, see Inheritance.

Processes that share files or memory must create file views by using the MapViewOfFile or MapViewOfFileEx function. They must coordinate their access using semaphores, mutexes, events, or some other mutual exclusion technique. For more information, see Synchronization.

A shared file-mapping object will not be destroyed until all processes that use it close their handles to it by using the CloseHandle function.


File-Mapping Security and Access Rights

Windows NT/Windows 2000 security enables you to control access to file-mapping objects. For more information about security, see Access-Control Model.

You can specify a security descriptor for a file-mapping object when you call the CreateFileMapping function. To retrieve the security descriptor of a file-mapping object, call the GetNamedSecurityInfo or GetSecurityInfo function. To set the security descriptor of a file-mapping object, call the SetNamedSecurityInfo or SetSecurityInfo function.

The valid access rights for file-mapping objects include the DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER standard access rights. File-mapping objects do not support the SYNCHRONIZE standard access right. The following table lists the specific access rights for file-mapping objects.

Value | Meaning
FILE_MAP_COPY | Copy on write access. If you create the map with PAGE_WRITECOPY and the view with FILE_MAP_COPY, you will receive a view to the mapped file. If you write to the mapped view, the modifications do not change the original data file.
FILE_MAP_READ | Read-only access. The file-mapping object must be created with PAGE_READWRITE or PAGE_READONLY protection. A read-only view of the file is mapped.
FILE_MAP_WRITE | Read and write access. The file-mapping object must be created with PAGE_READWRITE protection. A read/write view of the file is mapped.
FILE_MAP_ALL_ACCESS | Includes all access rights to a file-mapping object. The MapViewOfFile and MapViewOfFileEx functions treat this the same as if you had specified FILE_MAP_WRITE.

You can request the ACCESS_SYSTEM_SECURITY access right to a file-mapping object if you want to read or write the object's SACL. For more information, see Access-Control Lists (ACLs) and SACL Access Right.


Using File Mapping

The following code samples illustrate how two processes might access an existing file as named shared memory:

  • Creating named shared memory
  • Reading and writing
  • Cleaning up

As discussed earlier in this overview, the processes must synchronize their access to the memory. For more information, see Synchronization.


Creating Named Shared Memory

The first process calls the CreateFileMapping function to create a file-mapping object and give it the name MyFileMappingObject. By using the PAGE_READWRITE flag, the processes will have read/write permission to the memory through any file views that are created.

HANDLE hMapFile;

hMapFile = CreateFileMapping(hFile,    // Current file handle.
    NULL,                              // Default security.
    PAGE_READWRITE,                    // Read/write permission.
    0,                                 // Max. object size.
    0,                                 // Size of hFile.
    "MyFileMappingObject");            // Name of mapping object.

if (hMapFile == NULL)
{
    ErrorHandler("Could not create file-mapping object.");
}

The process then uses the file-mapping object handle returned by CreateFileMapping in the call to MapViewOfFile to create a view of the file in the process's address space. The MapViewOfFile function returns a pointer to the file view.

LPVOID lpMapAddress;
lpMapAddress = MapViewOfFile(hMapFile, // Handle to mapping object.
    FILE_MAP_ALL_ACCESS,               // Read/write permission
    0,                                 // Max. object size.
    0,                                 // Size of hFile.
    0);                                // Map entire file.

if (lpMapAddress == NULL)
{
    ErrorHandler("Could not map view of file.");
}

The second process calls the OpenFileMapping function with the name MyFileMappingObject to use the same file-mapping object as the first process. Like the first process, the second process uses the MapViewOfFile function to obtain a pointer to the file view.

HANDLE hMapFile;
LPVOID lpMapAddress;

hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, // Read/write permission.
    FALSE,                             // Do not inherit the name
    "MyFileMappingObject");            // of the mapping object.

if (hMapFile == NULL)
{
    ErrorHandler("Could not open file-mapping object.");
}

lpMapAddress = MapViewOfFile(hMapFile, // Handle to mapping object.
    FILE_MAP_ALL_ACCESS,               // Read/write permission.
    0,                                 // Max. object size.
    0,                                 // Size of hFile.
    0);                                // Map entire file.

if (lpMapAddress == NULL)
{
    ErrorHandler("Could not map view of file.");
}


Reading and Writing

To read from a file view, a process dereferences the pointer returned by the MapViewOfFile function:

DWORD dwLength;

dwLength = *((LPDWORD) lpMapAddress);

The process also uses the pointer returned by MapViewOfFile to write to the file view:

*((LPDWORD) lpMapAddress) = dwLength;

The FlushViewOfFile function copies the specified number of bytes of the file view to the physical file, without waiting for the cached write operation to occur:

if (!FlushViewOfFile(lpMapAddress, dwBytesToFlush))
{
    ErrorHandler("Could not flush memory to disk.");
}

Note Reading from or writing to a file view can cause an exception. For example, accessing a mapped file that resides on a remote server can generate an exception if the connection to the server is lost. Exceptions can also occur because of a full disk, because the file is shared and a different process has locked a byte range, or because of an underlying device failure or memory allocation failure. To guard against exceptions due to input and output (I/O) errors, all attempts to access memory mapped files should be wrapped in structured exception handlers.

If you are mapping a compressed or sparse file on an NTFS partition, there is additional potential for an I/O error when paging in a portion of the file. In this case, the address space mapped by MapViewOfFile may not be backed by allocated disk space. This is because a sparse file can have regions of zeroes for which NTFS does not allocate disk space, and a compressed file can take up less disk space than the actual data that it represents. If you read from or write to a portion of a sparse or compressed file that is not backed by disk space, the operating system may try to allocate disk space. If the disk is full, this can result in an exception indicating an I/O error. For more information, see File Compression, Sparse Files, and Structured Exception Handling.


Cleaning Up

Each process uses the UnmapViewOfFile function to invalidate the pointer to the mapped memory. This destroys the file view in the address space of the process. If any pages of the file view have changed since the file view was mapped, UnmapViewOfFile also copies the changed pages to the file on disk.

if (!UnmapViewOfFile(lpMapAddress))
{
    ErrorHandler("Could not unmap view of file.");
}

When each process finishes using the file-mapping object and has umapped all views, it must close the file-mapping object's handle by calling CloseHandle.

CloseHandle(hMapFile);


File Mapping Reference

The following elements are used with file mapping:

  • File Mapping Functions


File Mapping Functions

The following functions are used with file mapping.

Function | Description
CreateFileMapping | Creates or opens a named or unnamed file-mapping object for the specified file.
FlushViewOfFile | Writes to the disk a byte range within a mapped view of a file.
MapViewOfFile | Maps a view of a file into the address space of the calling process.
MapViewOfFileEx | Maps a view of a file into the address space of the calling process.
OpenFileMapping | Opens a named file-mapping object.
UnmapViewOfFile | Unmaps a mapped view of a file from the calling process's address space.


CreateFileMapping

The CreateFileMapping function creates or opens a named or unnamed file-mapping object for the specified file.

HANDLE CreateFileMapping(
  HANDLE hFile,                       // handle to file
  LPSECURITY_ATTRIBUTES lpAttributes, // security
  DWORD flProtect,                    // protection
  DWORD dwMaximumSizeHigh,            // high-order DWORD of size
  DWORD dwMaximumSizeLow,             // low-order DWORD of size
  LPCTSTR lpName                      // object name
);

Parameters

hFile
[in] Handle to the file from which to create a mapping object. The file must be opened with an access mode compatible with the protection flags specified by the flProtect parameter. It is recommended, though not required, that files you intend to map be opened for exclusive access.

If hFile is INVALID_HANDLE_VALUE, the calling process must also specify a mapping object size in the dwMaximumSizeHigh and dwMaximumSizeLow parameters. In this case, CreateFileMapping creates a file-mapping object of the specified size backed by the operating-system paging file rather than by a named file in the file system. The file-mapping object can be shared through duplication, through inheritance, or by name. The initial contents of the pages in the file-mapping object are zero.

lpAttributes
[in] Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpAttributes is NULL, the handle cannot be inherited.

Windows NT/2000 or later: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new file-mapping object. If lpAttributes is NULL, the file-mapping object gets a default security descriptor.

flProtect
[in] Protection desired for the file view, when the file is mapped. This parameter can be one of the following values.
Value | Description
PAGE_READONLY | Gives read-only access to the committed region of pages. An attempt to write to or execute the committed region results in an access violation. The file specified by the hFile parameter must have been created with GENERIC_READ access.
PAGE_READWRITE | Gives read/write access to the committed region of pages. The file specified by hFile must have been created with GENERIC_READ and GENERIC_WRITE access.
PAGE_WRITECOPY | Gives copy on write access to the committed region of pages. The files specified by the hFile parameter must have been created with GENERIC_READ and GENERIC_WRITE access.

In addition, an application can specify certain section attributes by combining (using the bitwise OR operator) one or more of the following section attribute values with one of the preceding page protection values.
Value | Description
SEC_COMMIT | Allocates physical storage in memory or in the paging file on disk for all pages of a section. This is the default setting.
SEC_IMAGE | The file specified for a section's file mapping is an executable image file. Because the mapping information and file protection are taken from the image file, no other attributes are valid with SEC_IMAGE.
SEC_NOCACHE | All pages of a section are to be set as noncacheable. This attribute is intended for architectures requiring various locking structures to be in memory that is never fetched into the processor's. On 80x86 and MIPS machines, using the cache for these structures only slows down the performance as the hardware keeps the caches coherent. Some device drivers require noncached data so that programs can write through to the physical memory. SEC_NOCACHE requires either the SEC_RESERVE or SEC_COMMIT to also be set.
SEC_RESERVE | Reserves all pages of a section without allocating physical storage. The reserved range of pages cannot be used by any other allocation operations until it is released. Reserved pages can be committed in subsequent calls to the VirtualAlloc function. This attribute is valid only if the hFile parameter is INVALID_HANDLE_VALUE; that is, a file-mapping object backed by the operating system paging file.

dwMaximumSizeHigh
[in] High-order DWORD of the maximum size of the file-mapping object.
dwMaximumSizeLow
[in] Low-order DWORD of the maximum size of the file-mapping object. If this parameter and dwMaximumSizeHigh are zero, the maximum size of the file-mapping object is equal to the current size of the file identified by hFile.

An attempt to map a file with a length of zero in this manner fails with an error code of ERROR_FILE_INVALID. Applications should test for files with a length of zero and reject such files.

lpName
[in] Pointer to a null-terminated string specifying the name of the mapping object.

If this parameter matches the name of an existing named mapping object, the function requests access to the mapping object with the protection specified by flProtect.

If this parameter is NULL, the mapping object is created without a name.

If lpName matches the name of an existing event, semaphore, mutex, waitable timer, or job object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Name Spaces.

Windows 2000 or later: If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character.

Windows NT 4.0 and earlier: The name can contain any character except the backslash character.

Windows 95/98/Me: The name can contain any character except the backslash character. The empty string ("") is a valid object name.

Return Values

If the function succeeds, the return value is a handle to the file-mapping object. If the object existed before the function call, the function returns a handle to the existing object (with its current size, not the specified size) and GetLastError returns ERROR_ALREADY_EXISTS.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

After a file-mapping object has been created, the size of the file must not exceed the size of the file-mapping object; if it does, not all of the file's contents will be available for sharing.

If an application specifies a size for the file-mapping object that is larger than the size of the actual named file on disk, the file on disk is grown to match the specified size of the file-mapping object. If the file cannot be grown, this results in a failure to create the file-mapping object. GetLastError will return ERROR_DISK_FULL.

The handle that CreateFileMapping returns has full access to the new file-mapping object. It can be used with any function that requires a handle to a file-mapping object. File-mapping objects can be shared either through process creation, through handle duplication, or by name. For information on duplicating handles, see DuplicateHandle. For information on opening a file-mapping object by name, see OpenFileMapping.

Windows 95/98/Me: File handles that have been used to create file-mapping objects must not be used in subsequent calls to file I/O functions, such as ReadFile and WriteFile. In general, if a file handle has been used in a successful call to the CreateFileMapping function, do not use that handle unless you first close the corresponding file-mapping object.

Creating a file-mapping object creates the potential for mapping a view of the file but does not map the view. The MapViewOfFile and MapViewOfFileEx functions map a view of a file into a process's address space.

With one important exception, file views derived from a single file-mapping object are coherent, or identical, at a given time. If multiple processes have handles of the same file-mapping object, they see a coherent view of the data when they map a view of the file.

The exception has to do with remote files. Although CreateFileMapping works with remote files, it does not keep them coherent. For example, if two computers both map a file as writable, and both change the same page, each computer will only see its own writes to the page. When the data gets updated on the disk, it is not merged.

A mapped file and a file accessed by means of the input and output (I/O) functions (ReadFile and WriteFile) are not necessarily coherent.

To fully close a file-mapping object, an application must unmap all mapped views of the file-mapping object by calling UnmapViewOfFile, and close the file-mapping object handle by calling CloseHandle. The order in which these functions are called does not matter. The call to UnmapViewOfFile is necessary because mapped views of a file-mapping object maintain internal open handles to the object, and a file-mapping object will not close until all open handles to it are closed.

Note Terminal Services sessions can use shared memory blocks to transfer data between processes spawned by those sessions. If you do this, keep in mind that shared memory cannot be used in situations where both of the following conditions exist:

  • All of the processes using the shared memory block were not spawned by one session.
  • All of the sessions share the same user logon credential.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory mapped view. For more information, see Reading and Writing.

Example

To implement a mapping-object creation function that fails if the object already exists, an application can use the following code.

hMap = CreateFileMapping(...);

if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
{
    CloseHandle(hMap);
    hMap = NULL;
}
return hMap;

For example, see Creating Named Shared Memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

File Mapping Overview, File Mapping Functions, CloseHandle, DuplicateHandle, MapViewOfFile, MapViewOfFileEx, OpenFileMapping, ReadFile, SECURITY_ATTRIBUTES, UnmapViewOfFile, VirtualAlloc, WriteFile


FlushViewOfFile

The FlushViewOfFile function writes to the disk a byte range within a mapped view of a file.

BOOL FlushViewOfFile(
  LPCVOID lpBaseAddress,         // starting address
  SIZE_T dwNumberOfBytesToFlush  // number of bytes in range
);

Parameters

lpBaseAddress
[in] Pointer to the base address of the byte range to be flushed to the disk representation of the mapped file.
dwNumberOfBytesToFlush
[in] Specifies the number of bytes to flush. If dwNumberOfBytesToFlush is zero, the file is flushed from the base address to the end of the mapping.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Flushing a range of a mapped view causes any dirty pages within that range to be written to the disk. Dirty pages are those whose contents have changed since the file view was mapped.

When flushing a memory-mapped file over a network, FlushViewOfFile guarantees that the data has been written from the local computer, but not that the data resides on the remote computer. The server can cache the data on the remote side. Therefore, FlushViewOfFile can return before the data has been physically written to disk. However, you can cause FlushViewOfFile to return only when the physical write is complete by specifying the FILE_FLAG_WRITE_THROUGH flag when you open the file with the CreateFile function.

For example, see Reading and Writing.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

File Mapping Overview, File Mapping Functions, CreateFile, MapViewOfFile, UnmapViewOfFile


MapViewOfFile

The MapViewOfFile function maps a view of a file into the address space of the calling process.

To specify a suggested base address, use the MapViewOfFileEx function.

LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,   // handle to file-mapping object
  DWORD dwDesiredAccess,       // access mode
  DWORD dwFileOffsetHigh,      // high-order DWORD of offset
  DWORD dwFileOffsetLow,       // low-order DWORD of offset
  SIZE_T dwNumberOfBytesToMap  // number of bytes to map
);

Parameters

hFileMappingObject
[in] Handle to an open handle of a file-mapping object. The CreateFileMapping and OpenFileMapping functions return this handle.
dwDesiredAccess
[in] Specifies the type of access to the file view and, therefore, the protection of the pages mapped by the file. This parameter can be one of the following values.
Value | Meaning
FILE_MAP_WRITE | Read/write access. The hFileMappingObject parameter must have been created with PAGE_READWRITE protection. A read/write view of the file is mapped.
FILE_MAP_READ | Read-only access. The hFileMappingObject parameter must have been created with PAGE_READWRITE or PAGE_READONLY protection. A read-only view of the file is mapped.
FILE_MAP_ALL_ACCESS | Same as FILE_MAP_WRITE.
FILE_MAP_COPY Copy on write access. If you create the map with PAGE_WRITECOPY and the view with FILE_MAP_COPY, you will receive a view to file. If you write to it, the pages are automatically swappable and the modifications you make will not go to the original data file.

Windows 95/98/Me: You must pass PAGE_WRITECOPY to CreateFileMapping; otherwise, an error will be returned.

If you share the mapping between multiple processes using DuplicateHandle or OpenFileMapping and one process writes to a view, the modification is propagated to the other process. The original file does not change.

Windows NT/2000 or later: There is no restriction as to how the hFileMappingObject parameter must be created. Copy on write is valid for any type of view.

If you share the mapping between multiple processes using DuplicateHandle or OpenFileMapping and one process writes to a view, the modification is not propagated to the other process. The original file does not change.

dwFileOffsetHigh
[in] Specifies the high-order DWORD of the file offset where mapping is to begin.
dwFileOffsetLow
[in] Specifies the low-order DWORD of the file offset where mapping is to begin. The combination of the high and low offsets must specify an offset within the file that matches the system's memory allocation granularity, or the function fails. That is, the offset must be a multiple of the allocation granularity. Use the GetSystemInfo function, which fills in the members of a SYSTEM_INFO structure, to obtain the system's memory allocation granularity.
dwNumberOfBytesToMap
[in] Specifies the number of bytes of the file to map. If dwNumberOfBytesToMap is zero, the entire file is mapped.

Return Values

If the function succeeds, the return value is the starting address of the mapped view.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Mapping a file makes the specified portion of the file visible in the address space of the calling process.

Multiple views of a file (or a file-mapping object and its mapped file) are said to be "coherent" if they contain identical data at a specified time. This occurs if the file views are derived from the same file-mapping object. A process can duplicate a file-mapping object handle into another process by using the DuplicateHandle function, or another process can open a file-mapping object by name by using the OpenFileMapping function.

A mapped view of a file is not guaranteed to be coherent with a file being accessed by the ReadFile or WriteFile function:

  • Windows 95/98/Me: MapViewOfFile may require the swapfile to grow. If the swapfile cannot grow, the function fails.
  • Windows NT/2000 or later: If the file-mapping object is backed by the paging file (hFile is INVALID_HANDLE_VALUE), the paging file must be large enough to hold the entire mapping. If it is not, MapViewOfFile fails.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory mapped view. For more information, see Reading and Writing.

For example, see Creating Named Shared Memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

File Mapping Overview, File Mapping Functions, CreateFileMapping, DuplicateHandle, GetSystemInfo, MapViewOfFileEx, OpenFileMapping, UnmapViewOfFile, SYSTEM_INFO


MapViewOfFileEx

The MapViewOfFileEx function maps a view of a file into the address space of the calling process. This extended function allows the calling process to specify a suggested memory address for the mapped view.

LPVOID MapViewOfFileEx(
  HANDLE hFileMappingObject,   // handle to file-mapping object
  DWORD dwDesiredAccess,       // access mode
  DWORD dwFileOffsetHigh,      // high-order DWORD of offset
  DWORD dwFileOffsetLow,       // low-order DWORD of offset
  SIZE_T dwNumberOfBytesToMap, // number of bytes to map
  LPVOID lpBaseAddress         // starting address
);

Parameters

hFileMappingObject
[in] Handle to an open handle to a file-mapping object. The CreateFileMapping and OpenFileMapping functions return this handle.
dwDesiredAccess
[in] Specifies the type of access to the file-mapping object and, therefore, the page protection of the pages mapped by the file. This parameter can be one of the following values.
Value | Meaning
FILE_MAP_WRITE | Read-and-write access. The hFileMappingObject parameter must have been created with PAGE_READWRITE protection. A read/write view of the file is mapped.
FILE_MAP_READ | Read-only access. The hFileMappingObject parameter must have been created with PAGE_READWRITE or PAGE_READONLY protection. A read-only view of the file is mapped.
FILE_MAP_ALL_ACCESS | Same as FILE_MAP_WRITE.
FILE_MAP_COPY Copy on write access. If you create the map with PAGE_WRITECOPY and the view with FILE_MAP_COPY, you will receive a view to the file. If you write to it, the pages are automatically swappable and the modifications you make will not go to the original data file.

Windows 95/98/Me: You must pass PAGE_WRITECOPY to CreateFileMapping; otherwise, an error will be returned.

If you share the mapping between multiple processes using DuplicateHandle or OpenFileMapping and one process writes to a view, the modification is propagated to the other process. The original file does not change.

Windows NT/2000 or later: There is no restriction as to how the hFileMappingObject parameter must be created. Copy on write is valid for any type of view.

If you share the mapping between multiple processes using DuplicateHandle or OpenFileMapping and one process writes to a view, the modification is not propagated to the other process. The original file does not change.

dwFileOffsetHigh
[in] Specifies the high-order DWORD of the file offset where mapping is to begin.
dwFileOffsetLow
[in] Specifies the low-order DWORD of the file offset where mapping is to begin. The combination of the high and low offsets must specify an offset within the file that matches the system's memory allocation granularity, or the function fails. That is, the offset must be a multiple of the allocation granularity. Use the GetSystemInfo function, which fills in the members of a SYSTEM_INFO structure, to obtain the system's memory allocation granularity.
dwNumberOfBytesToMap
[in] Specifies the number of bytes of the file to map. If dwNumberOfBytesToMap is zero, the entire file is mapped.
lpBaseAddress
[in] Pointer to the memory address in the calling process's address space where mapping should begin. This must be a multiple of the system's memory allocation granularity, or the function fails. Use the GetSystemInfo function, which fills in the members of a SYSTEM_INFO structure, to obtain the system's memory allocation granularity. If there is not enough address space at the specified address, the function fails.

If lpBaseAddress is NULL, the operating system chooses the mapping address. In this case, this function is equivalent to the MapViewOfFile function.

Return Values

If the function succeeds, the return value is the starting address of the mapped view.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Mapping a file makes the specified portion of the file visible in the address space of the calling process.

If a suggested mapping address is supplied, the file is mapped at the specified address (rounded down to the nearest 64K boundary) if there is enough address space at the specified address. If there is not, the function fails.

Typically, the suggested address is used to specify that a file should be mapped at the same address in multiple processes. This requires the region of address space to be available in all involved processes. No other memory allocation, including use of the VirtualAlloc function to reserve memory, can take place in the region used for mapping:

  • Windows 95/98/Me: If the lpBaseAddress parameter specifies a base offset, the function succeeds only if the same memory region is available for the memory mapped file in all other 32-bit processes.
  • Windows NT/2000 or later: If the lpBaseAddress parameter specifies a base offset, the function succeeds if the given memory region is not already in use by the calling process. the system does not guarantee that the same memory region is available for the memory mapped file in other 32-bit processes.

Multiple views of a file (or a file-mapping object and its mapped file) are said to be "coherent" if they contain identical data at a specified time. This occurs if the file views are derived from the same file-mapping object. A process can duplicate a file-mapping object handle into another process by using the DuplicateHandle function, or another process can open a file-mapping object by name by using the OpenFileMapping function.

A mapped view of a file is not guaranteed to be coherent with a file being accessed by the ReadFile or WriteFile function.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory mapped view. For more information, see Reading and Writing.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

File Mapping Overview, File Mapping Functions, CreateFileMapping, DuplicateHandle, GetSystemInfo, OpenFileMapping, ReadFile, UnmapViewOfFile, SYSTEM_INFO, VirtualAlloc, WriteFile


OpenFileMapping

The OpenFileMapping function opens a named file-mapping object.

HANDLE OpenFileMapping(
  DWORD dwDesiredAccess,  // access mode
  BOOL bInheritHandle,    // inherit flag
  LPCTSTR lpName          // object name
);

Parameters

dwDesiredAccess
[in] Specifies the access to the file-mapping object.

Windows NT/2000 or later: This access is checked against any security descriptor on the target file-mapping object.

Windows 95/98/Me: Security descriptors on file-mapping objects are not supported.

This parameter can be one of the following values.
Value | Meaning
FILE_MAP_WRITE | Read-write access. The target file-mapping object must have been created with PAGE_READWRITE or PAGE_WRITE protection. Allows a read-write view of the file to be mapped.
FILE_MAP_READ | Read-only access. The target file-mapping object must have been created with PAGE_READWRITE or PAGE_READ protection. Allows a read-only view of the file to be mapped.
FILE_MAP_ALL_ACCESS | All access. The target file-mapping object must have been created with PAGE_READWRITE protection. Allows a read-write view of the file to be mapped.
FILE_MAP_COPY | Copy-on-write access. The target file-mapping object must have been created with PAGE_WRITECOPY protection. Allows a copy-on-write view of the file to be mapped.

bInheritHandle
[in] Specifies whether the returned handle is to be inherited by a new process during process creation. A value of TRUE indicates that the new process inherits the handle.
lpName
[in] Pointer to a string that names the file-mapping object to be opened. If there is an open handle to a file-mapping object by this name and the security descriptor on the mapping object does not conflict with the dwDesiredAccess parameter, the open operation succeeds.

Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly open an object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Name Spaces.

Windows 2000 or later: If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character.

Windows NT 4.0 and earlier: The name can contain any character except the backslash character.

Windows 95/98/Me: The name can contain any character except the backslash character. The empty string ("") is a valid object name.

Return Values

If the function succeeds, the return value is an open handle to the specified file-mapping object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The handle that OpenFileMapping returns can be used with any function that requires a handle to a file-mapping object.

For example, see Creating Named Shared Memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

File Mapping Overview, File Mapping Functions, CreateFileMapping


UnmapViewOfFile

The UnmapViewOfFile function unmaps a mapped view of a file from the calling process's address space.

BOOL UnmapViewOfFile(
  LPCVOID lpBaseAddress   // starting address
);

Parameters

lpBaseAddress
[in] Pointer to the base address of the mapped view of a file that is to be unmapped. This value must be identical to the value returned by a previous call to the MapViewOfFile or MapViewOfFileEx function.

Return Values

If the function succeeds, the return value is nonzero, and all dirty pages within the specified range are written "lazily" to disk.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Although an application may close the file handle used to create a file-mapping object, the system holds the corresponding file open until the last view of the file is unmapped:

  • Windows 95/98/Me: Files for which the last view has not yet been unmapped are held open with the same sharing restrictions as the original file handle.
  • Windows NT/2000 or later: Files for which the last view has not yet been unmapped are held open with no sharing restrictions.

For example, see Using Shared Memory in a Dynamic-Link Library.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

File Mapping Overview, File Mapping Functions, MapViewOfFile, MapViewOfFileEx


Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

  • The file (.chm) that contains the destination topic is not in the expected location.

    Remedy: Rerun the MSDN Library Setup.

  • The file (.chm) that contains the current topic or destination topic is out-of-date and the link is no longer valid.

    Remedy: Install the latest version of the MSDN Library.

  • The MSDN Library CD is not in the CD-ROM drive.

    Remedy: Insert the MSDN Library CD into the CD-ROM drive.