Mona the Monad
Mona the Monad

Reputation: 2435

Freed memory not causing page fault

In experimenting with reserving and committing virtual memory to a process, I allocated 64K bytes of memory with VirtualAlloc, memcpy'd a test string into it, printf'd it like a string, freed the memory with VirtualFree with the MEM_RELEASE flag, and printf'd it again. For some reason, no page fault is triggered. Why is this?

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

INT main(DWORD argc, LPSTR argv[]) {
    SYSTEM_INFO info;
    DWORD dwPageSize;
    DWORD dwMemSize;
    LPVOID lpvMem;

    GetSystemInfo(&info);
    dwPageSize = info.dwPageSize;
    dwMemSize = 16 * dwPageSize;

    lpvMem = VirtualAlloc((LPVOID) 0x00F00000, dwMemSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (!lpvMem) {
        printf("Error allocating virtual memory\n");
        return 1;
    }

    printf("lpvMem = 0x%08X\n", (UINT32) (UINT64) lpvMem);

    if (!memcpy(lpvMem, "I love foxes \\(^o^)/", 21)) {
        printf("Error copying memory (error code 0x%08X)\n", GetLastError());
        return 1;
    }

    printf("Before free: %s\n", (LPCSTR) lpvMem);
    VirtualFree(lpvMem, dwMemSize, MEM_RELEASE);
    printf("After free:  %s\n", (LPCSTR) lpvMem);

    fflush(stdout);

    return 0;
}

Output:

lpvPagedMemory = 0x00F00000
Before free: I love foxes \(^o^)/
After free:  I love foxes \(^o^)/

Upvotes: 1

Views: 437

Answers (1)

RbMm
RbMm

Reputation: 33716

This line:

VirtualFree(lpvMem, dwMemSize, MEM_RELEASE);

is an error. You are not checking what VirtualFree() returns, and the documentation says:

dwSize [in]
...
If the dwFreeType parameter is MEM_RELEASE, this parameter must be 0 (zero). The function frees the entire region that is reserved in the initial allocation call to VirtualAlloc.

So you need to use this instead:

VirtualFree(lpvMem, 0, MEM_RELEASE);

About the page fault - it can (and must) only happen after a successful call to VirtualFree().

Upvotes: 12

Related Questions