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

cit*_*kid 1 winapi memory-management virtual-memory

这很好

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

    LPVOID memory = VirtualAlloc(
        0,
        bytes-1, // 2GB - 1
        MEM_COMMIT,
        PAGE_READWRITE);
Run Code Online (Sandbox Code Playgroud)

在这里,一旦达到2GB,就会失败

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

    LPVOID memory = VirtualAlloc(
        0,
        bytes, // 2GB
        MEM_COMMIT,
        PAGE_READWRITE);
Run Code Online (Sandbox Code Playgroud)

Windows错误消息"参数不正确".为什么会这样?实际上我想分配更多的虚拟内存.

IIn*_*ble 8

An int是Windows平台上的32位签名数量.值2GB-1是最大可表示正值,而2GB具有最高位设置,并被解释为负值.

值的二进制表示形式为:

 3         2         1         0
10987654321098765432109876543210

01111111111111111111111111111111  2GB - 1
10000000000000000000000000000000  2GB
Run Code Online (Sandbox Code Playgroud)

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

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

typedef ULONG_PTR SIZE_T, *PSIZE_T;
Run Code Online (Sandbox Code Playgroud)

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

  • @citykid:使用Microsoft编译器时,`long`也是32位.如果可以使用C++ 11功能,则必须使用`unsigned long long`.或者只是使用`SIZE_T`. (2认同)