Mikubyte Mikubyte - 6 days ago 5
C++ Question

Why can't I reserve two contiguous memory regions in the same allocation without reserving both with a single call?

I have two memory regions I'm allocating with

VirtualAlloc
:
0x1E0000 (Size: 0x39000, Reserve)
and
0x219000 (Size: 0x3000, Commit)
. These are both within the same allocation boundary (which in this case is rounded to
0x40000 (64K*4)
), and the second region starts where the first ends.

Now forget the commit part for a minute. If I
MEM_RESERVE
the first
0x39000
and then
MEM_RESERVE
the next
0x3000
, I get
ERROR_INVALID_ADDRESS
. However, if I
MEM_RESERVE
both in one go,
0x39000+0x3000=0x3C000
, then it works, and I can use
MEM_COMMIT
to commit the second region successfully.

Why is that? Why can't I reserve each part on its own instead of as one big reserved region? After reserving the first region the remaining area within the allocation
(0x219000-0x21FFFF)
will have the
MEM_FREE
state, so how come I cannot reserve the first
0x3000
of the remaining
0x7000
in the allocation boundary?

Answer

You cannot have two separate reservations within the same allocation boundary.

From the documentation for VirtualAlloc:

lpAddress [in, optional] The starting address of the region to allocate. If the memory is being reserved, the specified address is rounded down to the nearest multiple of the allocation granularity.

(emphasis mine)

So your request to reserve memory starting at 0x219000 actually attempts to reserve memory starting at 0x210000, which is inside the existing allocation and hence illegal.

(It should also be noted that there is no guarantee that any particular region of virtual memory will be available for you to reserve; Windows may have already reserved it for some other purpose. Best practice is to always set the lpAddress parameter to NULL, allowing Windows to choose an address for you.)