为什么即使 运行 作为 64 位进程,VirtualAlloc 也会失败 2GB?

Why does VirtualAlloc fail for 2GB even when running as 64bit process?

运行良好

    int GB = 2;
    int bytes = GB * 1024 * 1024 * 1024;

    LPVOID memory = VirtualAlloc(
        0,
        bytes-1, // 2GB - 1
        MEM_COMMIT,
        PAGE_READWRITE);

在这里,我一达到 2GB,就失败了

    int GB = 2;
    int bytes = GB * 1024 * 1024 * 1024;

    LPVOID memory = VirtualAlloc(
        0,
        bytes, // 2GB
        MEM_COMMIT,
        PAGE_READWRITE);

带有 Windows 错误消息 "The parameter is incorrect"。为什么会这样?其实我想分配更多的虚拟内存。

一个int是Windows平台上的一个32位有符号数。值 2GB - 1 是最大的可表示正值,而 2GB 设置了最高位,并被解释为负值。

值的二进制表示是:

 3         2         1         0
10987654321098765432109876543210

01111111111111111111111111111111  2GB - 1
10000000000000000000000000000000  2GB

当值 2GB 传递给 VirtualAlloc 时,它被符号扩展并转换为 SIZE_T。结果值以二进制表示形式为 1111111111111111111111111111111110000000000000000000000000000000(十进制:18446744071562067968,十六进制:0xffffffff80000000)。换句话说:巨大。

如果您需要分配 2GB 或更多,请使用 SIZE_T 而不是 int。在basetsd.h中声明如下:

typedef ULONG_PTR SIZE_T, *PSIZE_T;

它足够大,可以识别跨越指针整个范围的计数或范围。