placement-new

Placement new breaks consts and references?

别来无恙 提交于 2019-11-30 09:15:13
问题 Following the discussion on my answer to this question, apparently: the following code is allowed struct Foo { int x; }; Foo f; Foo & f_ref = f; (&f) -> ~Foo (); new (&f) Foo (); int x = f_ref .x; but the following code is not allowed struct Foo { const int & x; // difference is const reference Foo (int & i) : x(i) {} }; int i; Foo f (i); Foo & f_ref = f; (&f) -> ~Foo (); new (&f) Foo (i); int x = f_ref .x; Because of $3.8/7 If, after the lifetime of an object has ended and before the storage

Can placement-new and vector::data() be used to replace elements in a vector?

て烟熏妆下的殇ゞ 提交于 2019-11-30 06:37:12
There are two existing questions about replacing vector elements that are not assignable: C++ Use Unassignable Objects in Vector How to push_back without operator=() for const members? A typical reason for an object to be non-assignable is that its class definition includes const members and therefore has its operator= deleted. std::vector requires that its element type be assignable. And indeed, at least using GCC, neither direct assignment ( vec[i] = x; ), nor a combination of erase() and insert() to replace an element works when the object is not assignable. Can a function like the

Passing null pointer to placement new

风流意气都作罢 提交于 2019-11-29 22:50:53
The default placement new operator is declared in 18.6 [support.dynamic] ¶1 with a non-throwing exception-specification: void* operator new (std::size_t size, void* ptr) noexcept; This function does nothing except return ptr; so it is reasonable for it to be noexcept , however according to 5.3.4 [expr.new] ¶15 this means that the compiler must check it doesn't return null before invoking the object's constructor: -15- [ Note: unless an allocation function is declared with a non-throwing exception-specification (15.4), it indicates failure to allocate storage by throwing a std::bad_alloc

Placement new and uninitialized POD members

雨燕双飞 提交于 2019-11-29 17:17:34
问题 Does the C++ standard guarantee that uninitialized POD members retain their previous value after a placement new? Or more precisely, will the following assert always be satisfied according to C++11? #include <cstdlib> #include <cassert> struct Foo { int alpha; // NOTE: Uninitialized int beta = 0; }; int main() { void* p = std::malloc(sizeof (Foo)); int i = some_random_integer(); static_cast<Foo*>(p)->alpha = i; new (p) Foo; assert(static_cast<Foo*>(p)->alpha == i); } Is the answer the same

char array as storage for placement new

被刻印的时光 ゝ 提交于 2019-11-29 14:09:29
问题 Is the following legal C++ with well-defined behaviour? class my_class { ... }; int main() { char storage[sizeof(my_class)]; new ((void *)storage) my_class(); } Or is this problematic because of pointer casting/alignment considerations? 回答1: Yes, it's problematic. You simply have no guarantee that the memory is properly aligned. While various tricks exist to get storage with proper alignment, you're best off using Boost's or C++0x's aligned_storage , which hide these tricks from you. Then you

Placement new breaks consts and references?

做~自己de王妃 提交于 2019-11-29 13:30:45
Following the discussion on my answer to this question , apparently: the following code is allowed struct Foo { int x; }; Foo f; Foo & f_ref = f; (&f) -> ~Foo (); new (&f) Foo (); int x = f_ref .x; but the following code is not allowed struct Foo { const int & x; // difference is const reference Foo (int & i) : x(i) {} }; int i; Foo f (i); Foo & f_ref = f; (&f) -> ~Foo (); new (&f) Foo (i); int x = f_ref .x; Because of $3.8/7 If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location

assignment of class with const member

眉间皱痕 提交于 2019-11-29 09:45:15
Consider the following code: struct s { const int id; s(int _id): id(_id) {} }; // ... vector<s> v; v.push_back(s(1)); I get a compiler error that 'const int id' cannot use default assignment operator. Q1. Why does push_back() need an assignment operator? A1. Because the current c++ standard says so. Q2. What should I do? I don't want to give up the const specifier I want the data to be copied A2. I will use smart pointers. Q3. I came up with a "solution", which seems rather insane: s& operator =(const s& m) { if(this == &m) return *this; this->~s(); return *new(this) s(m); } Should I avoid

Mixing operator new[] and placement new with ordinary delete[]

谁说胖子不能爱 提交于 2019-11-29 09:13:42
Just out of curiosity, is the following legal? X* p = static_cast<X*>(operator new[](3 * sizeof(X))); new(p + 0) X(); new(p + 1) X(); new(p + 2) X(); delete[] p; // Am I allowed to use delete[] here? Or is it undefined behavior? Similarly: X* q = new X[3](); (q + 2)->~X(); (q + 1)->~X(); (q + 0)->~X(); operator delete[](q); I'm pretty sure both give UB. §5.3.4/12 says the array form of a new expression may add some arbitrary amount of overhead to the amount of memory allocated. The array delete can/could then do something with the extra memory it expects to be there, but isn't since you didn't

C++ Is constructing object twice using placement new undefined behaviour?

谁都会走 提交于 2019-11-29 07:19:57
I have come across some code which has horrified me. Essentially it follows this pattern : class Foo { public: //default constructor Foo(): x(0), ptr(nullptr) { //do nothing } //more interesting constructor Foo( FooInitialiser& init): x(0), ptr(nullptr) { x = init.getX(); ptr = new int; } ~Foo() { delete ptr; } private: int x; int* ptr; }; void someFunction( FooInitialiser initialiser ) { int numFoos = MAGIC_NUMBER; Foo* fooArray = new Foo[numFoos]; //allocate an array of default constructed Foo's for(int i = 0; i < numFoos; ++i) { new( fooArray+ i) Foo( initialiser ); //use placement new to

Is it allowed to call destructor explicitly followed by placement new on a variable with fixed lifetime?

a 夏天 提交于 2019-11-29 05:32:09
I know that calling destructor explicitly can lead to undefined behavior because of double destructor calling, like here: #include <vector> int main() { std::vector<int> foo(10); foo.~vector<int>(); return 0; // Oops, destructor will be called again on return, double-free. } But, what if we call placement new to "resurrect" the object? #include <vector> int main() { std::vector<int> foo(10); foo.~vector<int>(); new (&foo) std::vector<int>(5); return 0; } More formally: What will happen in C++ (I'm interested in both C++03 and C++11, if there is a difference) if I explicitly call a destructor