为什么 VirtualAlloc 会因 lpAddress 大于 0x6ffffffffff 而失败

why does VirtualAlloc fail for lpAddress greater than 0x6ffffffffff

我想通过使用 VirtualAlloc 尝试映射非常远的地址(尽可能接近 64 位)到有效内存中,看看如何 "far" 我可以指向 64 位 C 程序的限制。

我设法到达了 0x6ffffffffff,这是一个 42 位地址,但是超过该地址的任何数字都会导致分配失败,错误代码为 0x57(参数不正确)。

这是我的代码:

#include <Windows.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    LPVOID mem;
    WCHAR message[] = L"Hello, World!";

    mem = VirtualAlloc (        
        (LPVOID)0x00006ffffffffff,
        4096,
        MEM_RESERVE | MEM_COMMIT,
        PAGE_READWRITE
    );

    if (mem == 0) {
        wprintf(L"%x.\n", GetLastError());
        system("pause");
        exit(-1);
    }

    memcpy(mem, message, sizeof(message));

    wprintf(L"[%llx] -> %ls\n", mem, mem);

    system("pause");

    return 0;
}

为什么我不能在上面使用 VirtualAlloc 0x6ffffffffff

说明您请求的地址不在可用范围内。尽管理论上存在 64 位可用地址范围,但实际上并非所有该范围都可用于用户模式应用程序。您可以通过调用 GetSystemInfo 并检查 lpMinimumApplicationAddresslpMaximumApplicationAddress 的值来找到允许的范围。如果您尝试保留此范围之外的地址,对 VirtualAlloc 的调用将失败并且错误代码设置为 ERROR_INVALID_PARAMETER.

请注意,这些最小值和最大值并不精确。当您接近极限时,您将开始观察 ERROR_INVALID_PARAMETER