我试图使用VirtualAlloc来保留和提交一个内存块,然后再对该块进行扩展。不幸的是,尽管ERROR_INVALID_ADDRESS说所请求的地址范围是空闲的,但它还是返回带错误的NULL。这是我的密码:
void* allocation = VirtualAlloc(NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
void* desiredNextAllocation = (char*)allocation + 4096;
MEMORY_BASIC_INFORMATION info;
size_t memory_info = VirtualQuery(desiredNextAllocation, &info, sizeof(info));
void* extended = VirtualAlloc(desiredNextAllocation, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);第一个分配返回0x00000000000d0000。对VirtualQuery的调用在“info”中生成以下数据:
BaseAddress 0x00000000000d1000 void *
AllocationBase 0x0000000000000000 void *
AllocationProtect 0x00000000 unsigned long
RegionSize 0x00000000000ff000 unsigned __int64
State 0x00010000 unsigned long
Protect 0x00000001 unsigned long
Type 0x00000000 unsigned long我将其解释为存在从0xd 1000开始的、处于MEM_FREE状态的0xff可用页面。那么,为什么我在0xd 1000处提交页面的尝试失败了呢?
我正在运行Windows 7,这是一个64位构建。
我读过几篇关于StackOverflow的VirtualAlloc文章,但它们似乎都暗示这段代码应该工作,就像我对文档的理解一样。
发布于 2015-04-26 12:16:00
发布于 2015-04-26 05:57:51
如果要为分配指定连续页,则要将分配地址空间与分配内存以备份地址空间分开。记住这一点,我们可以实现如下代码:
#include <windows.h>
#include <iostream>
#include <iomanip>
std::ostream &operator<<(std::ostream &os, MEMORY_BASIC_INFORMATION const &mi) {
return os << std::setw(20) << "Allocation Base: " << mi.AllocationBase << "\n"
<< std::setw(20) << "BaseAddress: " << mi.BaseAddress << "\n"
<< std::setw(20) << "Protection: " << mi.Protect << "\n"
<< std::setw(20) << "Region size: " << mi.RegionSize;
}
void show_page(void *page) {
MEMORY_BASIC_INFORMATION info;
VirtualQuery(page, &info, sizeof(info));
std::cout << info << "\n\n";
}
static const int page_size = 4096;
void *alloc_page(char *address) {
void *ret = VirtualAlloc(address, page_size, MEM_COMMIT, PAGE_READWRITE);
show_page(ret);
return ret;
}
int main() {
static const int region_size = 65536;
char * alloc = static_cast<char *>(VirtualAlloc(NULL, region_size, MEM_RESERVE, PAGE_READWRITE));
for (int i = 0; i < 4; i++)
alloc_page(alloc + page_size * i);
}举例结果:
Allocation Base: 00000000000C0000
BaseAddress: 00000000000C0000
Protection: 4
Region size: 4096
Allocation Base: 00000000000C0000
BaseAddress: 00000000000C1000
Protection: 4
Region size: 4096
Allocation Base: 00000000000C0000
BaseAddress: 00000000000C2000
Protection: 4
Region size: 4096
Allocation Base: 00000000000C0000
BaseAddress: 00000000000C3000
Protection: 4
Region size: 4096正如您所看到的,所有的分配现在都成功了。旁白:当您保留地址空间时,您可以分配的最小大小是64K (如上面所示)。您确实应该通过调用GetSystemInfo来获得页面大小和最小区域大小,并在它提供的SYSTEM_INFO结构中使用dwPageSize和dwAllocationGranularity。
https://stackoverflow.com/questions/29873860
复制相似问题