首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VirtualAlloc失败

VirtualAlloc失败
EN

Stack Overflow用户
提问于 2015-04-26 04:45:59
回答 2查看 2.7K关注 0票数 6

我试图使用VirtualAlloc来保留和提交一个内存块,然后再对该块进行扩展。不幸的是,尽管ERROR_INVALID_ADDRESS说所请求的地址范围是空闲的,但它还是返回带错误的NULL。这是我的密码:

代码语言:javascript
复制
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”中生成以下数据:

代码语言:javascript
复制
    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文章,但它们似乎都暗示这段代码应该工作,就像我对文档的理解一样。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-26 12:16:00

来自VirtualAlloc文档

如果要保留内存,则将指定地址舍入到分配粒度的最近倍数。

在这种情况下,地址0xd 1000被舍入为地址0xd0000,该地址已经被保留,因此无效。

票数 1
EN

Stack Overflow用户

发布于 2015-04-26 05:57:51

如果要为分配指定连续页,则要将分配地址空间与分配内存以备份地址空间分开。记住这一点,我们可以实现如下代码:

代码语言:javascript
复制
#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);
}

举例结果:

代码语言:javascript
复制
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结构中使用dwPageSizedwAllocationGranularity

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29873860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档