MSVC++ 2019 中的内存分配

问题描述

我对内存分配有疑问,尤其是在使用 MSVC2019 时。

我有一个编译为 x64 的 C++ 程序。 通过调试我看到,分配变量会导致非常高的指针地址,指向第一个 4GB 地址空间(32 位)上的位置。如果我在任务管理器中检查程序,我发现它只使用了大约 30-50MB 的内存。

实际上4GB以下的整个地址空间都没有使用时,变量没有分配到虚拟内存空间的下半部分是什么原因?

我希望分配从低地址开始,直到使用的第一个 4GB 空间,不需要为此分配空间。

为什么这对我来说很有趣: 我有一个包含超过 15 年旧 C++ 代码的大型软件,它并非处处都准备为 64 位,在许多地方它将指针转换为 32 位类型,因此指针已损坏。很可能原作者假设指针是 32 位的。当编译为 64 位时,这实际上也应该是正确的,因此程序没有使用太多内存,内存使用量不会超过 4GB。并且似乎使用 2010 年的编译器编译时不会出现此问题,可能是那时内存分配导致地址位于第一个 4GB 块中,即使为 x64 编译。

我的问题是: 这种分配策略是否会在 MSVC++ 2019 中产生某种影响?例如。指示他的编译器/链接器/内存管理器更喜欢在第一个 32 位空间中分配,直到不再需要?或者,为内存管理器提供的虚拟地址空间设置大小限制,例如。通过设置为 2GB,我可以实现永远不会有任何指针指向超过 4GB 的已分配块。这样,假设指针为 32 位,旧代码将在强制转换操作中幸存下来。

我已经尝试在链接器选项中为高内存感知设置 NO,并检查了堆参数,但没有任何帮助。

谢谢!

解决方法

欢迎来到虚拟内存的世界!事实上,为了动态分配内存,标准库恳请内核提供它。并且只有内核对提供给程序的虚拟地址负责。由于每个进程都有自己的虚拟地址转换器,因此可以为多个进程分配相同的虚拟地址。 作为程序员,你永远不应该担心这个。使用内核提供给您的内存地址并继续使用。如果您必须使用假设指针不能超过 32 位的遗留代码,您不应该在 64 位模式下编译它,而只能在 32 位模式下编译。