如何按顺序或在指定的地址分配内存?

How to allocate memory sequentially or at the indicated addresses?

本文关键字:地址 分配 内存 何按 顺序      更新时间:2023-10-16

我需要按顺序分配内存池。我没有想出比通过VirtualAlloc分配内存更好的办法,因为我需要控制页面的访问权限。但是当我尝试使用 VirtualAlloc 时,如果我指定要从中分配内存的地址,我可能会在池或空指针之间出现一个大洞。

_SYSTEM_INFO sys;
GetSystemInfo(&sys);
// 0x0000028ea9450000
LPVOID mem = VirtualAlloc(NULL, sys.dwPageSize * 2, MEM_COMMIT, PAGE_READWRITE);
// 0x0000028ea94d0000
LPVOID mem2 = VirtualAlloc(NULL, sys.dwPageSize * 2, MEM_COMMIT, PAGE_READWRITE);

在该代码中,我在两个内存位置之间有一个等于 525KB 的洞! 我知道,VirtualAlloc 和其他方法按页面(我的机器中有 4096 字节(进行分配,我需要它,但我不明白为什么地址之间有这么大的差异?

我可以在指定的地址分配内存,或者哪种算法使用 OC 来查找要分配的内存吗?

如果不指定映射内存位置的开始地址,内核将使用一些启发式方法来确定最佳位置。留下一些空白是其中的一部分。

分配连续地址空间块的常用方法,首先通过分配一个大区域来保留它们,覆盖整个地址空间,其中较小的大块头被分配到MEM_RESERVE标志中。完成后,您可以正确进行分配,使用lpAddress参数指定要放置它的特定地址。

SIZE_T sz1 = sys.dwPageSize * 4;
SIZE_T sz2 = sys.dwPageSize * 2;
SITE_T off = 0;
LPVOID base = VirtualAlloc(NULL, sys.dwPageSize * 2, MEM_RESERVE, PAGE_GUARD);
LPVOID mem = VirtualAlloc((BYTE*)base + off, sz1, MEM_COMMIT, PAGE_READWRITE);
off += sz1
LPVOID mem2 = VirtualAlloc((BYTE*)base + off, sz2, MEM_COMMIT, PAGE_READWRITE);