Then again that's exactly what I'm doing now, so I guess it's all good.
In any case, the class I'm working with now forms the backbone of most of my custom memory management library. As I mentioned, it allocates memory in one megabyte chunks. To simpify things downstream, these chunks are all aligned on one megabyte boundaries. To do that, I use VirtualAlloc() on Windows. I reserve the address space from 0x4000 0000 to 0x5000 0000 and commit one megabyte sections upon request.
I chose 0x4000 0000 to 0x5000 0000 because 0x5000 0000 to 0x6000 0000 I've been using for my experimental garbage collector and 0x6000 0000 on up is a bad choice for multiple reasons (such as system dll's being loaded there).
As an aside, mapping the Win32 address space was one of the most annoying things that I've ever done in my life. Everytime I convinced myself I knew what the layout looked like I found out something new. Or Microsoft would add a new feature like the /3GB switch. At this point I have my "rough guess" map and it's proven to be fairly reliable so far. *knock on wood*
In any case, these chunks are then used by various other suballocators. In all there's usually quite a bit of layering between an actual visible suballocator and this granddaddy suballocator.