我需要使用VirtualAlloc / VirtualAllocEx?
一个例子,我找到一个案例 - 如果我分配了4 GB的虚拟内存,那么如果我不使用所有这些,那么我就不会花费物理内存,如果我调整数组的大小,我不需要重新分配和复制旧数据到新数组。
struct T_custom_allocator; // which using VirtualAllocEx()
std::vector<int, T_custom_allocator> vec;
vec.reserve(4*1024*1024*1024); // allocated virtual memory (physical memory is not used)
vec.resize(16384); // allocated 16KB of physical memory
// ...
vec.resize(32768); // allocated 32KB of physical memory
// (no need to copy of first 16 KB of data)
如果我使用标准分配器,当我调整大小时,我需要复制数据:
std::vector<int> vec;
vec.resize(16384); // allocated 16KB of physical memory
// ...
vec.resize(32768); // allocated 32KB of physical memory
// and need to copy of first 16 KB of data
或者使用标准分配器,我必须花费4GB 的物理内存:
std::vector<int> vec;
vec.reserve(4*1024*1024*1024); // allocated 4GB of physical memory
vec.resize(16384); // no need to do, except changing a local variable of size
// ...
vec.resize(32768); // no need to do, except changing a local variable of size
但是,为什么这比realloc()更好? http://www.cplusplus.com/reference/cstdlib/realloc/
还有其他案例可以使用VirtualAlloc [Ex]吗?
答案 0 :(得分:12)
尚未提及的VirtualAllocEx
的另一个用途是在另一个进程的地址空间中分配内存。请注意,第一个参数是进程的句柄 - 该函数在该进程的虚拟地址空间内分配内存。
我之前通过在目标进程中强制执行LoadLibrary
调用将代码注入到另一个进程中时使用了这个。基本步骤如下:
GetWindowThreadProcessId
)。OpenProcess
。VirtualAllocEx
在该过程中分配一些内存。WriteProcessMemory
将您的DLL名称复制到该内存中。LoadLibrary
获取GetProcAddress
函数的地址。CreateRemoteThread
以在目标进程中启动LoadLibrary
调用,其中thread参数是您使用VirtualAllocEx
分配的内存(包含DLL的名称)。< / LI>
醇>
并不是说你需要了解所有这些,但我认为这是一个有趣的用例。
答案 1 :(得分:6)
VirtualAlloc
和VirtualAllocEx
以非常简单的术语分配原始页面,从malloc
到GlobalAlloc
的所有其他记忆功能都使用下面的VirtualAllocEx
。 VirtualAlloc
的问题在于它基本上是原始内存,没有可用的重新分配或重定位。因此,如果你的地址空间变得支离破碎,你就没有办法,只能释放和重建。
VirtualAlloc
的主要用例是当你需要编写自己的内存管理器时,比如说它可以产生巨大差异的SQL实现。或者,如果您正在实现即时编译器(JIT),因为您需要能够将编译的页面上的保护标志从读/写更改为读/执行,而不是触发数据执行保护。