为什么VS Debug构建将变量分配得这么远?

问题描述 投票:1回答:1

我使用的是Visual Studio 2019,我注意到在调试版本中,变量之间的分配距离是如此之远。我看着Project Properties并尝试在线搜索,但找不到任何东西。我在Debug和Release模式下都运行了以下代码,分别是输出。

int main() {
        int a = 3;
        int b = 5;
        int c = 8;
        int d[5] = { 10,10,10,10,10 };
        int e = 14;

        std::cout << "a: " << &a 
                << "\nb: " << &b
                << "\nc: " << &c 
                << "\nd_start: " << &d[0]
                << "\nd_end: "   << &d[4] + 1
                << "\ne: " << &e 
            << std::endl;
}

如您在下面看到的,变量按照您期望的方式分配(一个接一个),中间没有浪费的内存。即使最后一个变量e也已优化为在c和d之间插入。

// Release_x64 Build Ouput
a:          0000003893EFFC40
b:          0000003893EFFC44
c:          0000003893EFFC48
d_start:    0000003893EFFC50
d_end:      0000003893EFFC64
e:          0000003893EFFC4C    // e is optimized in between c and d

下面是使我感到困惑的输出。在这里您可以看到ab被分配了32个字节!因此,它们之间有28个字节的浪费/未初始化的内存。除int d[5]以外的其他变量也会发生相同的情况。 dc之后具有32个未初始化的字节,但在e之前仅具有24个未初始化的字节。

// Debug_x64 Build Output
a:          00000086D7EFF3F4
b:          00000086D7EFF414
c:          00000086D7EFF434
d_start:    00000086D7EFF458
d_end:      00000086D7EFF46C
e:          00000086D7EFF484

我的问题是为什么会这样? MSVC为什么将这些变量分配得相距如此之远,又是什么决定了分隔它们的空间大小,使得它们对于数组而言有所不同?

c++ visual-studio memory visual-c++ allocation
1个回答
0
投票

调试版本的分配存储与发布版本不同。特别是,调试版本在每个存储块的开头和结尾分配一些空间,因此其分配模式有所不同。

调试分配器还在其分配的块的开头和结尾处检查存储,以查看其是否已被损坏。

存储空间是按量化的块分配的,量子的数量未指定,但大约为16或32字节。因此,如果您分配了六个元素的DWORD数组(大小= 6 * sizeof(DWORD)字节= 24字节),则分配器实际上将提供32个字节(一个32字节的量子或两个16字节的量子)。因此,如果您编写元素[6](第七个元素),则会覆盖一些“死空间”,并且不会检测到错误。但是在发行版中,量子可能是8个字节,并且将分配三个8个字节的量子,并且写入数组的[6]元素将覆盖属于下一个块的一部分存储分配器数据结构。之后,一切都是艰难的。直到程序退出,错误才会出现!您可以为任何大小的量子构造类似的“边界条件”情况。因为两个版本的分配器的量子大小都是相同的,但是分配器的调试版本会为其自身目的添加隐藏空间,因此您将在调试和释放模式下获得不同的存储分配模式。

© www.soinside.com 2019 - 2024. All rights reserved.