C 有关Windows用户空间内存分配限制的问题
我正在尝试查看Windows中可以分配内存的最大地址。我使用C 有关Windows用户空间内存分配限制的问题,c,windows,winapi,virtual-memory,C,Windows,Winapi,Virtual Memory,我正在尝试查看Windows中可以分配内存的最大地址。我使用GetSystemInfo获取最大地址,然后尝试分配一个4KB页面。我注意到一些我以前从未见过的行为,我想知道是否有人能解释为什么会发生这种情况。首先,这里是我的测试代码: SYSTEM_INFO info; GetSystemInfo(&info); PVOID base = (PUCHAR)info.lpMaximumApplicationAddress - info.dwPageSize; SIZE_T size = i
GetSystemInfo
获取最大地址,然后尝试分配一个4KB页面。我注意到一些我以前从未见过的行为,我想知道是否有人能解释为什么会发生这种情况。首先,这里是我的测试代码:
SYSTEM_INFO info;
GetSystemInfo(&info);
PVOID base = (PUCHAR)info.lpMaximumApplicationAddress - info.dwPageSize;
SIZE_T size = info.dwPageSize;
LPVOID mem = VirtualAlloc(base, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
以下是我注意到的几件事
0x7FFFFFFFF0000
。分配大小为64KB时,结束地址为7fffffff0000
,仅比最高用户地址多一个字节。这不是越界了吗info.dwAllocationGranularity
。页面大小可能是4K,但粒度是64K。页面分配必须是粒度的偶数倍。因此,您指定的基址将向下舍入到下一个最低粒度边界。文档中对此进行了讨论:
lpAddress
要分配的区域的起始地址。如果内存被保留,指定的地址将向下舍入到分配粒度的最近倍数。如果内存已被保留且正在提交,则地址将向下舍入到下一页边界。要确定主机上的页面大小和分配粒度,请使用函数。如果此参数为空,系统将确定在何处分配区域
另见
在您的情况下,info.lpMaximumApplicationAddress
很可能是0x7FFFFFEFFFF
(64K小于8TB,这是Windows 8及更早版本支持的最大内存;Windows 8.1的缓冲限制为128TB)。从中减去4K即为0x7FFFFFEEFFF
,然后四舍五入为0x7FFFFFF0000
,是64K的偶数倍
分配的基址是0x7FFFFFF0000。分配大小为64KB时,结束地址为7FFFFF0000,仅比最高用户地址多一个字节。这不是越界了吗
<代码>信息.LpMulMax Apple TrimeAdv>代码>类似于一个数组的1-前端指针,或一个标准C++容器的<代码>端()/<代码>迭代器。这是一个最大地址,你不应该去过去,甚至取消引用。您最多可以访问该最大地址的内存地址,但不包括它。
解释得很清楚,谢谢!