[英]Operator new behaves differently in Debug mode than in Release mode in MSVC
在测试有关页面错误的一些事情时,我发现new
在 MSVC 中的调试模式和发布模式下的运行方式之间存在奇怪的差异。 考虑以下代码1 :
#include <array>
constexpr size_t PAGE_SIZE = 4096;
int main()
{
const size_t count = 1000000;
char* const mem = new char[PAGE_SIZE * count];
// page align the pointer, c-style casts used for brevity
auto* pages = (std::array<char, PAGE_SIZE>*)((size_t)mem - (size_t)mem % PAGE_SIZE + PAGE_SIZE);
for (int i = 0; i < count; ++i)
pages[i][0] = 'a';
}
该代码在大多数架构上分配了一百万个正常的 memory 页。 然后它物理地写入这个分配的 memory,因此 memory 确实必须“给予”程序2 - 而不仅仅是以某种方式为它“保留”。 奇怪的是,当这真的发生时。 为了对此进行调查,我使用 Visual Studio 调试器逐步完成了代码,并查看了任务管理器中的 memory 使用图。 结果如下:
红色时间点是正在启动的程序,绿色时间点/时间间隔是对new char[]
的调用,蓝色时间点/时间间隔是for
循环。
事实证明,在调试模式下, new
的“保留”和“给予”memory 给程序。 同时,在发布模式下,它只“保留”它,因为 memory 是由循环“给定”的。 我只期望发布模式中存在的行为 - 我认为 memory 仅在发生页面错误时才“给予”程序。
为什么new
会这样? 这有什么重大影响吗?
1顺便说一句,由于某种原因,将auto* pages
更改为auto* const pages
会导致内部编译器错误。
2我对正确的术语有点困惑,所以我改用了“given”和“reserved”。
调试版本为您做了很多很酷的事情来帮助您找到错误。 一种是将已知值写入程序的 memory 中,这样您将更容易识别出您已经搞砸了未初始化的存储。 这意味着new
的调试版本获取 memory 并立即使用它,从而迫使系统在绿色区域中找到并移交真正的 memory,而不是将这项昂贵的任务推迟到程序在蓝色区域中实际使用它时。
用可识别的模式调试new
填充 memory。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.