在MSDN中,我发现以下内容`
BaseAddress-指向页面区域的基地址的指针。
AllocationBase-指向VirtualAlloc函数分配的页面范围的基地址的指针。 BaseAddress成员指向的页面包含在此分配范围内。
但是我不明白到底有什么区别。谁能告诉我与众不同? (不像在MSDN中那样:))
最佳答案
Windows上的虚拟内存分配的粒度为64 KB,即SYSTEM_INFO.dwAllocationGranularity的值。但是虚拟内存页为4096字节,即SYSTEM_INFO.dwPageSize的值。
当您使用VirtualAlloc分配虚拟内存时,您将始终获得一块其BaseAddress等于AllocationBase的块。但是,如果您随后更改了该块中一个或多个页面的页面保护,则可以观察到该块被不同的BaseAddress分割了。最好与示例程序一起显示,在MSVC++上运行此程序:
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <conio.h>
void showmem(void* mem) {
MEMORY_BASIC_INFORMATION info = {};
VirtualQuery(mem, &info, sizeof info);
printf("Alloc = %p, base = %p, size = %d, protect = %d\n",
info.AllocationBase, info.BaseAddress, info.RegionSize, info.Protect);
}
int main() {
BYTE* mem = (BYTE*)VirtualAlloc(0, 65536, MEM_COMMIT, PAGE_READWRITE);
printf("%s", "Initial allocation:\n");
showmem(mem);
DWORD oldprotect;
BOOL ok = VirtualProtect(mem + 4096, 4096, PAGE_NOACCESS, &oldprotect);
printf("%s", "\nAfter protection changes:\n");
showmem(mem);
showmem(mem + 4096);
showmem(mem + 4096 + 4096);
_getch();
return 0;
}
该程序的示例输出:
Initial allocation:
Alloc = 00ED0000, base = 00ED0000, size = 65536, protect = 4
After protection changes:
Alloc = 00ED0000, base = 00ED0000, size = 4096, protect = 4
Alloc = 00ED0000, base = 00ED1000, size = 4096, protect = 1
Alloc = 00ED0000, base = 00ED2000, size = 57344, protect = 4
并注意VirtualProtect()调用是如何要求将原始块分为3个区域的,这些区域具有不同的BaseAddress但具有相同的AllocationBase。