citykid
citykid

Reputation: 11040

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

This runs fine

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

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

while here, as soon as I reach 2GB, it fails

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

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

with Windows error message "The parameter is incorrect". Why is this the case? Actually I would like to allocate even much more virtual memory.

Upvotes: 2

Views: 1309

Answers (1)

IInspectable
IInspectable

Reputation: 51345

An int is a 32-bit signed quantity on the Windows platform. The value 2GB - 1 is the largest representable positive value, whereas 2GB has the topmost bit set, and is interpreted as a negative value.

The binary representation of the values is:

 3         2         1         0
10987654321098765432109876543210

01111111111111111111111111111111  2GB - 1
10000000000000000000000000000000  2GB

When the value 2GB is passed to VirtualAlloc, it is sign-extended and converted to a SIZE_T. The resulting value is 1111111111111111111111111111111110000000000000000000000000000000 in binary representation (dec: 18446744071562067968, hex: 0xffffffff80000000). In other words: huge.

If you need to allocate 2GB or more, use a SIZE_T instead of an int. It is declared in basetsd.h as follows:

typedef ULONG_PTR SIZE_T, *PSIZE_T;

It is large enough to identify counts or ranges that span the entire range of a pointer.

Upvotes: 9

Related Questions