[New - Windows NT]
VirtualAllocEx功能在指定进程的虚拟地址空间中保留,提交或同时存储内存区域。该函数初始化其分配给零的内存。
VirtualAllocEx功能与VirtualAlloc功能之间的区别在于VirtualAlloc在调用进程的地址空间内分配内存,而VirtualAllocEx则可以指定进程。
LPVOID VirtualAllocEx(
HANDLE 【hProcess】, | //在其中分配内存的进程 |
LPVOID 【lpAddress】, | //所需的分配起始地址 |
DWORD 【的dwSize】, | //要分配的区域的大小(以字节为单位) |
DWORD 【flAllocationType】, | //分配类型 |
DWORD 【//访问类型保护】 | //访问类型保护 |
); |
参数
【hProcess】
处理过程。该函数在该进程的虚拟地址空间内分配内存。
您必须具有PROCESS_VM_OPERATION访问权限。如果没有,则该函数失败。
【lpAddress】
指针,指定要分配的页面的所需起始地址。
如果您保留内存,该函数会将该地址舍入到最接近的64千字节边界。
如果提交已经保留的内存,该函数会将该地址舍入到最接近的页面边界。要确定主机上的页面大小,请使用GetSystemInfo功能。
如果【lpAddress】为NULL,则该函数确定在哪里分配该区域。
【的dwSize】
指定要分配的内存区域的大小(以字节为单位)。
如果【lpAddress】为NULL,则函数将返回【的dwSize】直到下一页边界。
如果【lpAddress】不为NULL,则该函数将分配包含一个或多个字节的所有页面,范围从【lpAddress】到(【lpAddress】 + 【的dwSize】)。这意味着,例如,跨越页面边界的2字节范围会导致功能分配两个页面。
【flAllocationType】
一组位标志,指定内存分配的类型。您可以设置以下一个或多个标志:
旗 | 含义 |
MEM_COMMIT | 该函数在内存页面的指定区域的内存或磁盘上的分页文件中分配实际物理存储。该函数将内存初始化为零。 |
提交已经提交的内存页的尝试不会导致该函数失败。这意味着您可以在不首先确定每个页面的当前承诺状态的情况下提交一系列页面。 如果内存页面尚未保留,则设置此标志会使该函数保留并提交内存页面。 | |
MEM_RESERVE | 该函数保留一系列的进程的虚拟地址空间,而不会在内存或磁盘上的页面文件中分配任何实际物理存储。 其他内存分配功能(如的malloc和LocalAlloc)在释放之前不能使用内存的保留范围。 您可以在后续调用VirtualAllocEx功能时提交保留的内存页。 |
MEM_TOP_DOWN | 该函数在最高可能的地址分配内存。 |
【//访问类型保护】
一组位标志,用于指定要分配的页面的访问保护。您可以根据需要指定以下标志之一以及PAGE_GUARD和PAGE_NOCACHE保护修饰符标志:
旗 | 含义 |
PAGE_READONLY | 启用对提交的页面区域的读取权限。尝试写入承诺的区域导致访问冲突。如果系统区分只读权限和执行权限,则尝试在提交的区域中执行代码会导致访问冲突。 |
PAGE_READWRITE | 启用对提交的页面区域的读取和写入权限。 |
PAGE_EXECUTE | 启用对提交的页面区域的执行权限。尝试读取或写入承诺的区域导致访问冲突。 |
PAGE_EXECUTE_READ | 启用对提交的页面区域的执行和读取权限。尝试写入承诺的区域导致访问冲突。 |
PAGE_EXECUTE_READWRITE | 对承诺的页面区域启用执行,读取和写入权限。 |
PAGE_GUARD | 该地区的页面变成了保护页面。任何从保护页面读取或写入的尝试都会导致操作系统引起STATUS_GUARD_PAGE异常并关闭保护页面状态。因此,保护??页面可以作为一次性访问报警。 PAGE_GUARD标志是页面保护修饰符。应用程序使用它与其他页面保护标志之一,但有一个例外:它不能与PAGE_NOACCESS一起使用。当访问尝试导致操作系统关闭保护页面状态时,底层页面保护将接管。 如果在系统服务期间发生保护页异常,则该服务通常返回故障状态指示符。 |
PAGE_NOACCESS | 禁用对提交的页面区域的所有访问。在承诺区域中读取,写入或执行的尝试导致访问冲突异常,称为通用保护(GP)故障。 |
PAGE_NOCACHE | 不允许缓存已提交的页面区域。物理内存的硬件属性应指定为“无缓存”。这是不推荐一般用途。它对于设备驱动程序是有用的;例如,映射没有缓存的视频帧缓冲区。此标志是页面保护修饰符,仅当与PAGE_NOACCESS之外的页面保护之一使用时才有效。 |
一组位标志,用于指定要分配的页面的访问保护。您可以根据需要指定以下标志之一以及PAGE_GUARD和PAGE_NOCACHE保护修饰符标志:
返回值
如果函数成功,则返回值是分配的页面区域的基址。
如果函数失败,返回值为NULL。要获取扩展错误信息,请调用GetLastError.
备注
VirtualAllocEx功能可以执行以下操作:
*提交由VirtualAllocEx函数先前调用保留的页面区域。
*保留一个免费页面的区域。
*保留并提交一个免费页面的区域。
您可以使用VirtualAllocEx预留一个页面块,然后对VirtualAllocEx进行其他调用,从保留块中提交单个页面。这样,您可以在不需要物理存储的情况下预留一系列进程的虚拟地址空间,直到需要。
进程的虚拟地址空间中的每一页内存都是三种状态之一:
州 | 含义 |
自由 | 该页面未提交或保留,并且该进程不可访问。VirtualAllocEx功能可以保留或同时保留和提交免费页面。 |
保留的 | 页面保留。其他分配功能不能使用地址范围,但该页面不可访问,并且没有与之相关的物理存储。VirtualAllocEx功能可以提交保留页面,但不能再次保留。您可以使用VirtualFreeEx功能在指定的进程中发布保留页面,使其成为一个免费的页面。 |
承诺 | 为页面分配物理存储,访问由保护代码控制。只有在首次尝试读取或写入该页面时,系统才会将每个已提交的页面初始化并加载到物理内存中。当进程终止时,系统释放已提交页面的存储。VirtualAllocEx功能可以提交已经提交的页面。这意味着您可以提交一系列页面,无论它们是否已被提交,并且该函数不会失败。您可以使用VirtualFreeEx函数在指定的进程中解除已提交的页面,或同时解除并释放已提交的页面。 |
如果【lpAddress】参数不为NULL,则该函数使用【lpAddress】和【的dwSize】参数来计算要分配的页面的区域。整个页面范围的当前状态必须与【flAllocationType】参数指定的分配类型兼容。否则,该函数失败,并且没有页面被分配。这种兼容性要求不排除提交已经提交的页面;请参见前面的列表。
PAGE_GUARD保护修饰符标志建立防护页。保护页作为单次访问警报。有关详细信息,请参阅守卫页.
也可以看看
GlobalAlloc, HeapAlloc, VirtualAlloc, VirtualFree, VirtualFreeEx, VirtualLock, VirtualProtect, VirtualQuery