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:
#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:
warning C6386: Buffer overrun while writing to 'first': the writable size is '10' bytes, but '18' bytes might be written.
At first the bytes are written as expected:
But the compiler wasn't bluffing. At the placement new statement it does write 18 bytes:
Which results in an error:
Run-Time Check Failure #2 - Stack around the variable 'first' was corrupted.
Why doesn't it stick to 10 bytes? sizeof(MyChar)==1
and alignof(MyChar)==1
.
(*) Microsoft Visual Studio Community 2017 Preview (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).
placement new of array may require more place than N * sizeof(Object)
(??? as compiler has to be able to call correctly the destructor with delete[]
???).
5.3.4 [expr.new]:
new(2,f) T[5]
results in a call ofoperator new[](sizeof(T)*5+y,2,f)
.Here,
x
andy
are non-negative unspecified values representing array allocation overhead; the result of the new-expression will be offset by this amount from the value returned byoperator new[]
. This overhead may be applied in all array new-expressions, including those referencing the library functionoperator new[](std::size_t, void*)
and other placement allocation functions. The amount of overhead may vary from one invocation of new to another. —end example ]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.