The virtual memory API directly allocates virtual memory. Windows CE also uses the virtual memory API to allocate memory for the heap and the stack. Use the virtual memory API when you need to reserve and allocate large blocks of memory for an application. The advantage of using virtual memory is that virtual memory does not fragment: Windows CE always allocates an integral number of pages. However, because Windows CE manages virtual memory in 64-KB units, you must ensure that you use all of the memory efficiently. Typically, an application wastes half of a virtual memory page per allocation. Also, Windows CE requires a slight overhead for managing the memory mapping. Finally, you must remember the reserved and committed status of each page. Therefore, if you do not think that you can use most of the 64-KB unit in your virtual memory allocation, use a heap instead.
You can also use VirtualAlloc to reserve virtual memory and then have Windows CE map the memory address directly to physical memory when the pages are actually used by the application.
Decomitting a page unmaps the page from physical memory but keeps the virtual addresses reserved for the application.
The following code example shows how to simultaneously reserve and commit virtual memory.
#define THIRTY_K (30 * 1024) // Definition example
LPVOID lpMemory = NULL; // Pointer to a region of memory
LPVOID lpPage = NULL; // Pointer to a page of memory
lpMemory = VirtualAlloc (NULL, THIRTY_K,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (NULL == lpMemory)
{
// Your error-handling code goes here. You can use the
// GetLastError function to obtain more information.
}
// Your code that uses the just-allocated memory goes here.
// For example: LPBYTE MyPointer = (LPBYTE)lpMemory;
// memset (MyPointer, 0, THIRTY_K);
// return MyPointer;
// . . .
// When you are finished with the memory, you must release it.
if (!VirtualFree (lpMemory, 0, MEM_RELEASE))
{
// Your error-handling code goes here. You can use the
// GetLastError function to obtain more information.
}
// Remember to clear the pointer to prevent re-use.
lpMemory = NULL;
The following code example shows how to reserve a bundle of memory and then commit that memory, as needed.
lpMemory = VirtualAlloc (NULL, THIRTY_K,
MEM_RESERVE, PAGE_READWRITE);
if (NULL == lpMemory)
{
// Your error-handling code goes here. You can use the
// GetLastError function to obtain more information.
}
// Determine the page size on this system.
SYSTEM_INFO siSystemInfo;
GetSystemInfo (&siSystemInfo);
// Commit the first page of the just-reserved block.
// (To commit more than one page, multiply the dwPageSize
// parameter used below by the number of pages to commit.)
lpPage = VirtualAlloc (lpMemory, // Base for this commit
siSystemInfo.dwPageSize,
// number of bytes
// to commit
MEM_COMMIT, // Selects the operation
PAGE_READWRITE); // Selects permissions
if (NULL == lpPage)
{
// Your error-handling code goes here. You can use the
// GetLastError function to obtain more information.
}
// To commit additional pages, add the appropriate
// offset to 'lpMemory' and call VirtualAlloc again.
// For example, to commit the tenth page:
// lpPage = VirtualAlloc ((LPBYTE)lpMemory + 9 * dwPageSize,
// and so on.
// . . .
The following code example shows how to use the VirtualQuery function to examine the characteristics of a page of virtual memory that you previously allocated.
DWORD dwResult;
MEMORY_BASIC_INFORMATION mbiMemory;
// Clear the results structure.
memset (&mbiMemory, 0, sizeof(MEMORY_BASIC_INFORMATION));
dwResult = VirtualQuery (lpPage, // Page to examine
&mbiMemory, // Structure for results
sizeof(MEMORY_BASIC_INFORMATION));
if (sizeof(MEMORY_BASIC_INFORMATION) != dwResult)
{
// Your error-handling code goes here.
}
// Here, write code to use the contents of the mbiMemory
// structure that was filled in by the above call.
// For example: if (mbiMemory.Protect != PAGE_READWRITE)
// and so on.
// . . .
The following code example shows how to use VirtualProtect to change the characteristics of a page of virtual memory that you previously allocated.
DWORD dwOldProtect;
DWORD dwSize = 2048; // Or, set this to 'siSystemInfo.dwPageSize'
// (See the above code for how to get this.)
if (!VirtualProtect (lpPage, // Beginning of the set of
// pages to change
dwSize, // Length, in bytes, of the
// set of pages to change
PAGE_READONLY, // What to change it to
&dwOldProtect // Place to store the old setting
))
{
// Your error-handling code goes here. You can use the
// GetLastError function to obtain more information.
}
The following code example shows how to decommit a page by using VirtualFree. Presumably, you could recommit the page later with different attributes.
if (!VirtualFree (lpPage, 0, MEM_DECOMMIT))
{
// Your error-handling code goes here. You can use the
// GetLastError function to obtain more information.
}