I am trying to allocate a certain amount of memory within some memory range in a DLL that gets loaded within a Windows Application.
The way I am doing it, is using VirtualQuery()
to search for a region of memory that is marked as free and is within the boundaries where I require to do the allocation. What I am seeing is that even though the region is marked as MEM_FREE
VirtualAlloc()
fails sometimes to allocate the memory.
The code is very close to the following:
LPVOID address = NULL, mem = NULL;
for (address = LOWER_RANGE; address < UPPER_RANGE;) {
MEMORY_BASIC_INFORMATION mbi = {0};
if (VirtualQuery(address, &mbi, sizeof(mbi))) {
if (mbi.State == MEM_FREE && mbi.RegionSize >= ALLOC_SIZE) {
mem = VirtualAlloc(address, ALLOC_SIZE,
MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READ);
if (mem) {
break;
}
}
}
address = mbi.BaseAddress + mbi.RegionSize;
}
When VirtualAlloc()
fails, GetLastError()
returns ERROR_INVALID_ADDRESS
(487).
The way I have worked around it is, if it is big enough, scan through mbi.RegionSize
using page size steps to find an address that will allow me to allocate the memory that I need.
Why is it that according to VirtualQuery
the entire region should be free and I should be able to allocate inside any address I want, but usually when the first VirtualAlloc
fails I have to loop for several steps until it is finally successful.