VirtualAlloc是一个Windows API函数,该函数的功能是在调用进程的虚地址空间,预定或者提交一部分页。
VirtualAlloc是一个Windows API函数,该函数的功能是在调用进程的虚地址空间,预定或者提交一部分页。
简单点的意思就是申请内存空间
VirtualAlloc是一个Windows API函数,它包含在windows系统文件Kernel32.dll中,编程时直接使用就可以了,不需要再下载。
该函数的功能是在调用进程的虚地址空间,预定或者提交一部分页
如果用于内存分配的话,并且分配类型未指定MEM_RESET,则系统将自动设置为0;
LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的内存区域的地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的类型
DWORD flProtect // 该内存的初始保护属性
};
该函数的功能是在调用进程的虚地址空间,预定或者提交一部分页
如果用于内存分配的话,并且分配类型未指定MEM_RESET,则该内存自动被初始化为0;
LPVOID lpAddress, 分配内存区域的地址。当你使用VirtualAlloc来提交一块以前保留的内存块的时候,lpAddress参数可以用来识别以前保留的内存块。如果这个参数是NULL,系统将会决定分配内存区域的位置,并且按64-KB向上取整(roundup)。
SIZE_T dwSize, 要分配或者保留的区域的大小。这个参数以字节为单位,而不是页,系统会根据这个大小一直分配到下页的边界DWORD
flAllocationType, 分配类型 ,你可以指定或者合并以下标志:MEM_COMMIT,MEM_RESERVE和MEM_TOP_DOWN。
DWORD flProtect 指定了被分配区域的访问保护方式
分配类型 功能
可能的数值 | 含义 |
|---|---|
MEM_COMMIT 0x1000 | 为指定地址空间提交物理内存。这个函数初始化内在为零 试图提交已提交的内存页不会导致函数失败。这意味着您可以在不确定当前页的当前提交状态的情况下提交一系列页面。 如果尚未保留内存页,则设置此值会导致函数同时保留并提交内存页。 |
MEM_RESERVE 0x2000 | 保留指定地址空间,不分配物理内存。 这样可以阻止其他内存分配函数malloc和LocalAlloc等再使用已保留的内存范围,直到它被被释放。 当使用上面的VirtualAlloc函数保留了一段地址空间后,接下还你还可以继续多次调用同样的函数提交这段地址空间中的不同页面。 |
MEM_RESET0x80000 | 表示,在所指定的内存范围内的数据lpAddress的dwSize不再是利益。页面不应该被读出或写入到分页文件。然而,将再次使用的内存块后,所以它不应该decommitted的 。这个值不能使用任何其他的价值 。 使用这个值并不保证范围与经营MEM_RESET将包含零。如果你想的范围包含零,decommit内存,然后将它重新作出 。 当您指定MEM_RESET,VirtualAlloc函数忽略值flProtect。但是,您仍然必须设置flProtect有效的值,比如,PAGE_NOACCESS。 如果你使用MEM_RESET的内存范围映射到一个文件,VirtualAlloc返回一个错误。如果它被映射到分页文件共享视图是唯一可以接受的的 。 |
分配类型 也可以是下列值
可能的数值 | 含义 |
|---|---|
MEM_LARGE_PAGES0x20000000的 | 分配内存使用大页面支持。 大小和对齐必须是一个大页面的最低多个 。要获得这个值,使用GetLargePageMinimum。 |
MEM_PHYSICAL0x400000 | 储备的地址范围,可用于内存地址窗口扩展(AWE)的页面。 此值必须使用MEM_RESERVE,并没有其他值。 |
MEM_TOP_DOWN0x100000 | 在尽可能高的地址分配内存。这可以比普通的分配速度较慢,尤其是当需要许多分配。 |
MEM_WRITE_WATCH0x200000 | 导致系统来跟踪分配的地区,都写在页面 。如果指定此值,则还必须指定MEM_RESERVE。 要检索的页面是否写入,因为该地区被分配或写跟踪状态被重置地址,调用GetWriteWatch功能。要重置写跟踪状态,调用GetWriteWatch或ResetWriteWatch。写跟踪功能仍然启用,直到该地区被释放。 |
访问类型
PAGE_READonLY 0x02 | 该区域为只读。如果应用程序试图访问区域中的页的时候,将会被拒绝访问。 |
PAGE_EXECUTE 0x10 | 区域包含可被执行的代码。试图读写该区域的操作将被拒绝。 |
PAGE_EXECUTE_READ 0x20 | 区域包含可执行代码,应用程序只能读该区域。 |
PAGE_READWRITE 0x04 | 区域不可执行代码,应用程序可以读写该区域。 |
PAGE_EXECUTE_READWRITE 0x40 | 区域可以执行代码,应用程序可以读写该区域。 |
PAGE_GUARD 0x100 | 区域第一次被访问时进入一个STATUS_GUARD_PAGE异常,这个标志要和其他保护标志合并使用,表明区域被第一次访问的权限 |
PAGE_NOACCESS 0x01 | 任何访问该区域的操作将被拒绝 |
PAGE_NOCACHE 0x200 | RAM中的页映射到该区域时将不会被微处理器缓存(cached) |
注:PAGE_GUARD和PAGE_NOCHACHE标志可以和其他标志合并使用以进一步指定页的特征。PAGE_GUARD标志指定了一个防护页(guard page),即当一个页被提交时会因第一次被访问而产生一个one-shot异常,接着取得指定的访问权限。PAGE_NOCACHE防止当它映射到虚拟页的时候被微处理器缓存。这个标志方便设备驱动使用直接内存访问方式(DMA)来共享内存块。
如果调用成功,返回分配的首地址,
调用失败,返回NULL 你可以通过GetLastError函数来获取错误信息
VirtualAlloc可以通过并行多次调用提交一个区域的部分或全部来保留一个大的内存区域。多重调用提交同一块区域不会引起失败。这使得一个应用程序保留内存后可以随意提交将被写的页。当这种方式不在有效的时候,它会释放应用程序通过检测被保留页的状态看它是否在提交调用之前已经被提交