简体   繁体   English

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

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

In the following program I expected 10 bytes to be overwritten with placement new and then for the destructor to be called for each byte: 在下面的程序中,我希望用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;
}

But the compiler (*) warns that 18 will be written: 但编译器(*)警告将写入18:

warning C6386: Buffer overrun while writing to 'first': the writable size is '10' bytes, but '18' bytes might be written. 警告C6386:写入'first'时缓冲区溢出:可写大小为'10'字节,但可能写入'18'字节。

At first the bytes are written as expected: 首先,字节按预期写入: 在此输入图像描述

But the compiler wasn't bluffing. 但是编译器并没有虚张声势。 At the placement new statement it does write 18 bytes: 在放置新语句时,它写入18个字节: 在此输入图像描述

Which results in an error: 这会导致错误:

Run-Time Check Failure #2 - Stack around the variable 'first' was corrupted. 运行时检查失败#2 - 变量'first'周围的堆栈已损坏。

Why doesn't it stick to 10 bytes? 为什么不坚持10个字节? sizeof(MyChar)==1 and alignof(MyChar)==1 . sizeof(MyChar)==1alignof(MyChar)==1


(*) Microsoft Visual Studio Community 2017 Preview (2). (*)Microsoft Visual Studio社区2017预览(2)。 Also (but without warning during compilation) I get the same memory overwritten and runtime error on Microsoft Visual Studio Community 2017 (Version 15.2 (26430.15) Release). 另外(但在编译期间没有警告)我在Microsoft Visual Studio Community 2017(版本15.2(26430.15)发行版)上获得了相同的内存覆盖和运行时错误。

placement new of array may require more place than N * sizeof(Object) 放置新数组可能需要比N * sizeof(Object)更多的位置

(??? as compiler has to be able to call correctly the destructor with delete[] ???). (因为编译器必须能够使用delete[] ???)正确调用析构函数。

5.3.4 [expr.new]: 5.3.4 [expr.new]:

new(2,f) T[5] results in a call of operator new[](sizeof(T)*5+y,2,f) . new(2,f) T[5]导致operator new[](sizeof(T)*5+y,2,f)的调用operator new[](sizeof(T)*5+y,2,f)

Here, x and y are non-negative unspecified values representing array allocation overhead; 这里, xy是非负的未指定值,表示数组分配开销; the result of the new-expression will be offset by this amount from the value returned by operator new[] . new-expression的结果将由operator new[]返回的值抵消。 This overhead may be applied in all array new-expressions, including those referencing the library function operator new[](std::size_t, void*) and other placement allocation functions. 这种开销可以应用于所有数组新表达式,包括那些引用库函数operator new[](std::size_t, void*)和其他放置分配函数的表达式。 The amount of overhead may vary from one invocation of new to another. 开销的数量可能因新的一次调用而异。 —end example ] - 末端的例子]

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

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