Reputation: 89
I need to allocate memory pools sequentially. I didn't come up with anything better than allocating memory through VirtualAlloc, because I need to control the access permissions of the pages. But when I try to use VirtualAlloc I can get a big hole between pools or null pointer if I specify the address from which to allocate memory.
_SYSTEM_INFO sys;
GetSystemInfo(&sys);
// 0x0000028ea9450000
LPVOID mem = VirtualAlloc(NULL, sys.dwPageSize * 2, MEM_COMMIT, PAGE_READWRITE);
// 0x0000028ea94d0000
LPVOID mem2 = VirtualAlloc(NULL, sys.dwPageSize * 2, MEM_COMMIT, PAGE_READWRITE);
In that code I have a hole between two memory places equal to 525KB! I know, that VirtualAlloc and other methods does allocations by page(4096 bytes in my machine) and I need it, but I dont understand why is there such a big difference between addresses?
Can I allocate memory at the specified address or or which algorithm uses OC to find memory for allocation?
Upvotes: 4
Views: 247
Reputation: 162164
Without specifying a start address for where to map the memory, the kernel will use some heuristics to determine the best place. Leaving some gap is part of that.
The usual way to allocate consecutive blocks of address space, you first reserve them by allocating a large region, covering the whole address space into which smaller hunks are allocated with the MEM_RESERVE
flag. After that's done you do the allocation proper, specifying the specific address where you want it to be placed, using the lpAddress
parameter.
SIZE_T sz1 = sys.dwPageSize * 4;
SIZE_T sz2 = sys.dwPageSize * 2;
SITE_T off = 0;
LPVOID base = VirtualAlloc(NULL, sys.dwPageSize * 2, MEM_RESERVE, PAGE_GUARD);
LPVOID mem = VirtualAlloc((BYTE*)base + off, sz1, MEM_COMMIT, PAGE_READWRITE);
off += sz1
LPVOID mem2 = VirtualAlloc((BYTE*)base + off, sz2, MEM_COMMIT, PAGE_READWRITE);
Upvotes: 3