了解 VirtualAlloc 中的基地址
Understanding base addresses in VirtualAlloc
在我的应用程序中,我试图在启动时通过 VirtualAlloc 分配一大块内存(大约 1GB-2GB),然后我可以稍后将其划分以供应用程序的其余部分使用。在调试模式下,我想在 VirtualAlloc 调用中传递一个基地址,以保持指针地址一致以便于调试,但我正在努力理解什么是我可以使用的有效基地址。
这是进行分配的代码片段
s32 CALLBACK WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, s32 showCode)
{
SYSTEM_INFO info = {};
GetSystemInfo(&info);
// In my case info.lpMinimumApplicationAddress gives me 64kb
LPVOID base = info.lpMinimumApplicationAddress;
u32 totalSize = MEGABYTES(8);
void *test = VirtualAlloc(base, totalSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
...
}
该应用程序是 Windows 的 64 位版本上的 x86 运行,根据我发现的以下信息:
https://www.tenouk.com/WinVirtualAddressSpace.html
仅供应用程序保留的虚拟内存space 应在4MB 到2GB 之间。但是当我尝试像上面的代码片段一样分配少量内存时,基地址为 64KB(由系统信息给出)或根据引用的网站 VirtualAlloc returns 0 在 4MB 左右。我我尝试使用 VirtualQueryEx 调查虚拟内存 space,我能找到的最大内存块大小约为 2GB,但基地址为 2GB。根据上面的信息,这意味着我正在分配给可能有潜在危险的系统内存?
简而言之,我想知道是否有人可以澄清我在该网站上提到的信息是否准确,以及使用 1GB 或 2GB 的大基址是否安全?我对解决方案的唯一其他想法是扫描虚拟地址 space 以获得足够大的块,并使用我找到的第一个作为基地址,但我不确定该基地址是否会在连续为了调试而运行。
提前致谢。
链接的文章适用于 32 位模式。在 64 位模式下,保留地址从 128 TB 开始。 MSDN says 内容如下:
For a 32-bit process, the virtual address space is usually the 2-gigabyte range 0x00000000 through 0x7FFFFFFF. For a 64-bit process on 64-bit Windows, virtual address space is the 128-terabyte range 0x000'00000000 through 0x7FFF'FFFFFFFF. A range of virtual addresses is sometimes called a range of virtual memory. For more info, see Memory and Address Space Limits.
所以你很安全。
但是您根本不应该关心或探查基地址 - 只需传递 NULL
作为基地址,VirtualAlloc
将为您 select 一个:
lpAddress
The starting address of the region to allocate. If the memory is being reserved, the specified address is rounded down to the nearest multiple of the allocation granularity.
. . .
If this parameter is NULL
, the system determines where to allocate the region.
在我的应用程序中,我试图在启动时通过 VirtualAlloc 分配一大块内存(大约 1GB-2GB),然后我可以稍后将其划分以供应用程序的其余部分使用。在调试模式下,我想在 VirtualAlloc 调用中传递一个基地址,以保持指针地址一致以便于调试,但我正在努力理解什么是我可以使用的有效基地址。
这是进行分配的代码片段
s32 CALLBACK WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, s32 showCode)
{
SYSTEM_INFO info = {};
GetSystemInfo(&info);
// In my case info.lpMinimumApplicationAddress gives me 64kb
LPVOID base = info.lpMinimumApplicationAddress;
u32 totalSize = MEGABYTES(8);
void *test = VirtualAlloc(base, totalSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
...
}
该应用程序是 Windows 的 64 位版本上的 x86 运行,根据我发现的以下信息: https://www.tenouk.com/WinVirtualAddressSpace.html
仅供应用程序保留的虚拟内存space 应在4MB 到2GB 之间。但是当我尝试像上面的代码片段一样分配少量内存时,基地址为 64KB(由系统信息给出)或根据引用的网站 VirtualAlloc returns 0 在 4MB 左右。我我尝试使用 VirtualQueryEx 调查虚拟内存 space,我能找到的最大内存块大小约为 2GB,但基地址为 2GB。根据上面的信息,这意味着我正在分配给可能有潜在危险的系统内存?
简而言之,我想知道是否有人可以澄清我在该网站上提到的信息是否准确,以及使用 1GB 或 2GB 的大基址是否安全?我对解决方案的唯一其他想法是扫描虚拟地址 space 以获得足够大的块,并使用我找到的第一个作为基地址,但我不确定该基地址是否会在连续为了调试而运行。
提前致谢。
链接的文章适用于 32 位模式。在 64 位模式下,保留地址从 128 TB 开始。 MSDN says 内容如下:
For a 32-bit process, the virtual address space is usually the 2-gigabyte range 0x00000000 through 0x7FFFFFFF. For a 64-bit process on 64-bit Windows, virtual address space is the 128-terabyte range 0x000'00000000 through 0x7FFF'FFFFFFFF. A range of virtual addresses is sometimes called a range of virtual memory. For more info, see Memory and Address Space Limits.
所以你很安全。
但是您根本不应该关心或探查基地址 - 只需传递 NULL
作为基地址,VirtualAlloc
将为您 select 一个:
lpAddress
The starting address of the region to allocate. If the memory is being reserved, the specified address is rounded down to the nearest multiple of the allocation granularity. . . . If this parameter is
NULL
, the system determines where to allocate the region.