Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
A version of this page is also available for
4/8/2010

This function allows users to create a heap with a custom allocator or deallocator function.

Syntax

HANDLE CeHeapCreate(
  DWORD 
flOptions,
  DWORD 
dwInitialSize,
  DWORD 
dwMaximumSize,
  PFN_AllocHeapMem 
pfnAlloc,
  PFN_FreeHeapMem 
pfnFree
);

Parameters

flOptions

[in] Reserved. This parameter must be set to zero.

dwInitialSize

[in] 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 GetSystemInfofunction.

dwMaximumSize

[in] If dwMaximumSizeis a nonzero value, it specifies the maximum size, in bytes, of the heap.

CeHeapCreaterounds dwMaximumSizeup to the next page boundary and then reserves a block of that size in the virtual address space of the process for the heap.

If allocation requests made by HeapAllocor HeapReAllocexceed the initial amount of physical storage space specified by dwInitialSize, the system allocates additional pages of physical storage for the heap, up to the heap's maximum size.

If dwMaximumSizeis nonzero, the heap cannot grow and an absolute limitation arises where all allocations are fulfilled within the specified heap unless there is not enough free space.

If dwMaximumSizeis zero, it specifies that the heap can grow and the heap's size is limited only by available memory.

Requests to allocate blocks larger than 0x0018000 bytes do not automatically fail. The system calls VirtualAllocto obtain the memory needed for such large blocks.

Applications that need to allocate large memory blocks should set dwMaximumSizeto zero.

pfnAlloc

[in] The allocator function.

pfnFree

[in] The deallocator function.

Return Value

A handle to the heap indicates success. NULL indicates failure.

Remarks

The following code sample shows an implementation that uses a single reservation on the physical memory.

It is possible to use the physical memory on a page-by-page basis if you maintain a free list of the physical memory. In such a case, you use the VirtualFreefunction on the pages during MEM_COMMIT and MEM_DECOMMIT.

Copy Code
// Assuming there are some fast memory available on a platform at
physical 
// address 0x40000000, of size 0x80000.
// The following code creates a heap on using this memory when
possible.
//
#define  PHYS_MEM_ADDR 0x40000000
#define  PHYS_MEM_SIZE 0x00080000
//
BOOL g_fPhysMemUsed;
//
// The allocator
LPVOID MyAllocMem (LPVOID pAddr, DWORD cbSize, DWORD fdwAction,
LPDWORD pdwData)
{
   LPVOID lpRet = NULL;
   switch (fdwAction) {
	case MEM_RESERVE:
	// Reserve VM using VirtualAlloc
	if (!(lpRet = VirtualAlloc (pAddr, cbSize, MEM_RESERVE,
PAGE_NOACCESS))) {
		 SetLastError (ERROR_OUTOFMEMORY);
		 break;
}
	// Use the physical memory if possible
	if (!g_fPhysMemUsed && (cbSize <= PHYS_MEM_SIZE))
{
		 // Yes, physical memory is available, use VirtualCopy
		 if (!VirtualCopy (lpRet, (LPVOID) (PHYS_MEM_ADDR >>
8), cbSize, PAGE_READWRITE|PAGE_PHYSICAL)) {
			 SetLastError (ERROR_OUTOFMEMORY);
			 break;
		 }
		 g_fPhysMemUsed = TRUE;
		 *pdwData = PHYS_MEM_ADDR;
} 
	else {
		 *pdwData = 0;   // Indicates this is not using physical
memory
}
	break;
	case MEM_COMMIT:
	// MEM_COMMIT should not change the content of *pdwData, as
the data
	// is a 'per-reservation' information.
	if (PHYS_MEM_ADDR  == *pdwData) {
		 // This is using physical memory, already committed
		 lpRet = pAddr;
} 
	else {
		 lpRet = VirtualAlloc (pAddr, cbSize, MEM_COMMIT,
PAGE_READWRITE);
}
	break;
	default:
	// This should never happen
		 DEBUGCHK (0);
		 break;
   }
return lpRet;
}
//
// The de-allocator
//
BOOL MyFreeMem (LPVOID pAddr, DWORD cbSize, DWORD fdwAction, DWORD
dwData)
{
   BOOL fRet = FALSE;
   switch (fdwAction) {
	case MEM_DECOMMIT:
		 if (PHYS_MEM_ADDR  == dwData) {
			// This is using physical memory; never needs to
decommit
			break;
		 }
		 // VirtualAlloc'd data, decommit the memory
		 fRet = VirtualFree (pAddr, cbSize, MEM_DECOMMIT);
		 break;
	case MEM_RELEASE:
		 // Release the reservation
		 fRet = VirtualFree (pAddr, 0, MEM_RELEASE);
		 if (fRet && (PHYS_MEM_ADDR  == dwData)) {
			// Physical memory is released and is available again
			g_fPhysMemUsed = TRUE;
		 }
		 break;
	default:
	// This should never happen
		 DEBUGCHK (0);
		 break;
}
   return fRet;
}
//
// To create a heap with the custom allocator/de-allocator
int MyFunc ()
{
   HANDLE hHeap = CeHeapCreate (0, 0, 0, MyAllocMem, MyFreeMem);
   LPVOID p;
   if (hHeap) {
	// Heap creation failed
	// ErrorHandling ();
	return 0;
   }
   // Ordinary heap operation can be performed on the heap
   p = HeapAlloc (hHeap, 0, 100);  
   HeapFree (hHeap, 0, p);
   //...
   // Finish using the heap, destroy it
   HeapDestroy (hHeap);
	return 0;
}

Requirements

Header winbase.h
Library coredll.lib
Windows Embedded CE Windows CE 5.0 and later
Windows Mobile Windows Mobile Version 5.0 and later

See Also