gpt4 book ai didi

c++ - VirtualAlloc 失败

转载 作者:可可西里 更新时间:2023-11-01 13:26:10 28 4
gpt4 key购买 nike

我正在尝试使用 VirtualAlloc 来保留和提交一 block 内存,然后再次扩展该 block 。不幸的是,尽管 VirtualQuery 说请求的地址范围是免费的,但它返回 NULL 和错误 ERROR_INVALID_ADDRESS。这是我的代码:

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 的调用导致“信息”中的以下数据:

    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

我将其解释为从 0xd1000 开始有 0xff 个可用页面处于 MEM_FREE 状态。那么,为什么我尝试提交位于 0xd1000 的页面会失败?

我运行的是 Windows 7,这是一个 64 位版本。

我已经阅读了几篇关于 VirtualAlloc 的 StackOverflow 帖子,但它们似乎都暗示这段代码应该像我对文档的理解一样工作。

最佳答案

如果要为分配指定连续的页面,则需要将分配地址空间与分配内存分开以支持它。牢记这一点,我们可以实现这样的代码:

#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 来获取页面大小和最小区域大小。 ,并使用 dwPageSizedwAllocationGranularitySYSTEM_INFO它为您提供的结构。

关于c++ - VirtualAlloc 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29873860/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com