Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I följande exempel visas användningen av funktionerna VirtualAlloc och VirtualFree för att reservera och spara minne efter behov för en dynamisk matris. Först anropas VirtualAlloc för att reservera ett block med sidor med NULL- som anges som basadressparameter, vilket tvingar systemet att fastställa platsen för blocket. Senare anropas VirtualAlloc- när det är nödvändigt att checka in en sida från den här reserverade regionen och basadressen för nästa sida som ska checkas in anges.
I exemplet används strukturerad syntax för undantagshantering för att checka in sidor från den reserverade regionen. När ett undantag för sidfel inträffar under exekveringen av __try-blocket, körs filterfunktionen i uttrycket som föregår __except-blocket. Om filterfunktionen kan allokera en annan sida fortsätter körningen i det __try blocket vid den punkt där undantaget inträffade. Annars körs undantagshanteraren i __except-blocket. Mer information finns i Strukturerad undantagshantering.
Som ett alternativ till dynamisk allokering kan processen helt enkelt tilldela hela regionen i stället för att bara reservera den. Båda metoderna resulterar i samma användning av fysiskt minne eftersom de allokerade sidorna inte förbrukar någon fysisk lagring innan de används för första gången. Fördelen med dynamisk allokering är att den minimerar det totala antalet bekräftade sidor i systemet. För mycket stora allokeringar kan förincheckning av en hel allokering leda till att systemet får slut på incheckbara sidor, vilket resulterar i virtuella minnesallokeringsfel.
Funktionen ExitProcess i __except-blocket utför en automatisk frigöring av virtuella minnesallokeringar, så det är inte nödvändigt att uttryckligen frigöra sidorna när programmet avslutas via denna exekveringsväg. Funktionen VirtualFree frigör reserverade och bekräftade sidor om programmet skapas med undantagshantering inaktiverat. Den här funktionen använder MEM_RELEASE för att ta bort och frigöra hela regionen med reserverade och bekräftade sidor.
I följande C++-exempel visas dynamisk minnesallokering med hjälp av en strukturerad undantagshanterare.
// A short program to demonstrate dynamic memory allocation
// using a structured exception handler.
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>             // For exit
#define PAGELIMIT 80            // Number of pages to ask for
LPTSTR lpNxtPage;               // Address of the next page to ask for
DWORD dwPages = 0;              // Count of pages gotten so far
DWORD dwPageSize;               // 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)
    {
        _tprintf(TEXT("Exception code = %d.\n"), dwCode);
        return EXCEPTION_EXECUTE_HANDLER;
    }
    _tprintf(TEXT("Exception is a page fault.\n"));
    // If the reserved pages are used up, exit.
    if (dwPages >= PAGELIMIT)
    {
        _tprintf(TEXT("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 )
    {
        _tprintf(TEXT("VirtualAlloc failed.\n"));
        return EXCEPTION_EXECUTE_HANDLER;
    }
    else
    {
        _tprintf(TEXT("Allocating another page.\n"));
    }
    // Increment the page count, and advance lpNxtPage to the next page.
    dwPages++;
    lpNxtPage = (LPTSTR) ((PCHAR) lpNxtPage + dwPageSize);
    // Continue execution where the page fault occurred.
    return EXCEPTION_CONTINUE_EXECUTION;
}
VOID ErrorExit(LPTSTR lpMsg)
{
    _tprintf(TEXT("Error! %s with error code of %ld.\n"),
             lpMsg, GetLastError ());
    exit (0);
}
VOID _tmain(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);     // Initialize the structure.
    _tprintf (TEXT("This computer has page size %d.\n"), sSysInfo.dwPageSize);
    dwPageSize = sSysInfo.dwPageSize;
    // Reserve pages in the virtual address space of the process.
    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(TEXT("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 code is executed only if the filter function
            // is unsuccessful in committing the next page.
            _tprintf (TEXT("Exiting process.\n"));
            ExitProcess( GetLastError() );
        }
    }
    // Release the block of pages when you are finished using them.
    bSuccess = VirtualFree(
                       lpvBase,       // Base address of block
                       0,             // Bytes of committed pages
                       MEM_RELEASE);  // Decommit the pages
    _tprintf (TEXT("Release %s.\n"), bSuccess ? TEXT("succeeded") : TEXT("failed") );
}