简体   繁体   English

在 MSVC 中,操作员 new 在调试模式下的行为与在发布模式下的行为不同

[英]Operator new behaves differently in Debug mode than in Release mode in MSVC

While testing some things regarding page faults I discovered a curious difference between how new operates in Debug mode and Release mode in MSVC.在测试有关页面错误的一些事情时,我发现new在 MSVC 中的调试模式和发布模式下的运行方式之间存在奇怪的差异。 Consider the following code 1 :考虑以下代码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';
}

The code allocates a million normal memory pages on most architectures.该代码在大多数架构上分配了一百万个正常的 memory It then physically writes to this allocated memory, so the memory really has to be "given" 2 to the program - not merely "reserved" for it in some way.然后它物理地写入这个分配的 memory,因此 memory 确实必须“给予”程序2 - 而不仅仅是以某种方式为它“保留”。 The curious thing is, when this actually happens.奇怪的是,当这真的发生时。 To investigate this, I stepped through the code using the Visual Studio debugger and looked at the memory usage graph in Task Manager.为了对此进行调查,我使用 Visual Studio 调试器逐步完成了代码,并查看了任务管理器中的 memory 使用图。 The results are below:结果如下:

测量结果

The red time point is the program being launched, the green time point/interval is the call to new char[] , the blue time point/interval is the for loop.红色时间点是正在启动的程序,绿色时间点/时间间隔是对new char[]的调用,蓝色时间点/时间间隔是for循环。

As it turns out, in Debug mode, new both "reserves" and "gives" memory to the program.事实证明,在调试模式下, new的“保留”和“给予”memory 给程序。 Meanwhile, in Release mode, it only "reserves" it, as the memory is "given" by the loop.同时,在发布模式下,它只“保留”它,因为 memory 是由循环“给定”的。 I expected only the behavior present in Release mode - I thought that the memory is "given" to the program only when a page fault occurs.我只期望发布模式中存在的行为 - 我认为 memory 仅在发生页面错误时才“给予”程序。

Why does new behave in this way?为什么new会这样? Does this have any significant implications?这有什么重大影响吗?


1 By the way, for some reason changing auto* pages to auto* const pages causes an Internal Compiler Error. 1顺便说一句,由于某种原因,将auto* pages更改为auto* const pages会导致内部编译器错误。

2 I am a bit confused regarding the correct terminology, so I used "given" and "reserved" instead. 2我对正确的术语有点困惑,所以我改用了“given”和“reserved”。

The debug builds do a lot of cool stuff for you to help you find bugs.调试版本为您做了很多很酷的事情来帮助您找到错误。 One is writing a known value into the program's memory so you'll more easily recognize that you've messed around with uninitialized storage.一种是将已知值写入程序的 memory 中,这样您将更容易识别出您已经搞砸了未初始化的存储。 This means the debug version of new acquires the memory and immediately uses it, forcing the system to find and hand over real memory in the green region rather than deferring that expensive task to when the program actually uses it in the blue region.这意味着new的调试版本获取 memory 并立即使用它,从而迫使系统在绿色区域中找到并移交真正的 memory,而不是将这项昂贵的任务推迟到程序在蓝色区域中实际使用它时。

Debug new fills memory with recognizable pattern.用可识别的模式调试new填充 memory。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM