Suppose I am allocating an arbitrary block of memory. Part of this block is atomic data (ints, bytes, etc.) and some of this block of data I want to be occupied by objects. Can I turn any arbitrary piece of memory into an object through a constructor call, such as data->MyObject ()
and subsequently destroying the object via data->~MyObject()
, or is this impossible?
views:
201answers:
2Placement New:
std::vector<char> data(sizeof(X)); // Where X is a class
X* ptr = new (&data[0]) X(1,2,3);
// Work with ptr
ptr->~X();
As per comment below:
std::vector be default use '20.6.1 The default allocator' for retrieving storage. The default allocator method Allocator::allocate(n) '20.6.1.1' allocate enough storage for n objects of T (using n * sizeof(T)) aligned properly for objects of type 'T'. This storage is allocated by calling '::operator new(m)' 18.5.1.1.1 (where m is n * sizeof(T) in our case sizeof(X) * sizeof(char)) this allocates enough memory for the request aligned for any type of size m.
Thus by using
std::vector<char> data(sizeof(X))
This will allocate enough memory for an object of type X but it is also makes sure that it correctly aligned for objects of that type X. Note: As long as the amount of memory we try and reserve with the vector is at least as large as the object we want to align for then the standard guarantees that the memory will be correctly aligned.
Unfortunately statically allocated memory has no such guarantee. So people who use an array may be in for a shock.
char data[sizeof(X)];
X* ptr = new (&data[0]) X(1,2,3); // Oops. This alignment may not work.