繁体   English   中英

Placement new是写入比数组大小更多的字节

[英]Placement new is writing more bytes than array size

在下面的程序中,我希望用placement new覆盖10个字节,然后为每个字节调用析构函数:

#include <memory>

struct MyChar {
    MyChar(char c = 'n') :c{c}{}
    ~MyChar(){ c = 'd'; }
    char c;
};

int main()
{
    {
        MyChar first[10]{0,1,2,3,4,5,6,7,8,9};
        new (first)MyChar[10]{10,11,12,13,14,15,16,17,18,19};
    }
    return 0;
}

但编译器(*)警告将写入18:

警告C6386:写入'first'时缓冲区溢出:可写大小为'10'字节,但可能写入'18'字节。

首先,字节按预期写入: 在此输入图像描述

但是编译器并没有虚张声势。 在放置新语句时,它写入18个字节: 在此输入图像描述

这会导致错误:

运行时检查失败#2 - 变量'first'周围的堆栈已损坏。

为什么不坚持10个字节? sizeof(MyChar)==1alignof(MyChar)==1


(*)Microsoft Visual Studio社区2017预览(2)。 另外(但在编译期间没有警告)我在Microsoft Visual Studio Community 2017(版本15.2(26430.15)发行版)上获得了相同的内存覆盖和运行时错误。

放置新数组可能需要比N * sizeof(Object)更多的位置

(因为编译器必须能够使用delete[] ???)正确调用析构函数。

5.3.4 [expr.new]:

new(2,f) T[5]导致operator new[](sizeof(T)*5+y,2,f)的调用operator new[](sizeof(T)*5+y,2,f)

这里, xy是非负的未指定值,表示数组分配开销; new-expression的结果将由operator new[]返回的值抵消。 这种开销可以应用于所有数组新表达式,包括那些引用库函数operator new[](std::size_t, void*)和其他放置分配函数的表达式。 开销的数量可能因新的一次调用而异。 - 末端的例子]

暂无
暂无

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

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