Reputation: 2509
According to https://isocpp.org/wiki/faq/dtors#placement-new the address passed into placement-new has to be properly aligned. But the example it gives seems to contradict that.
char memory[sizeof(Fred)];
This buffer is most likely not aligned for Fred, since it's a dumb char[]
, so memory
can point to pretty much anywhere. Then it does placement-new on this address.
Is the example contradicting the alignment requirement it says in the DANGER footnote?
That leads to a related question:
How can I create a buffer (either stack or heap) that is aligned for a type T
(to use in placement-new of one or more T objects)?
By buffer I mean a char[]
or void*
buffer of some size, not a T[]
because that would be object allocation which defeats the point of doing placement-new afterwards.
Thank you.
Upvotes: 15
Views: 2575
Reputation: 10490
About your first question: according to the answers to this related question yes, the example got it wrong:
Statically allocated arrays are aligned to sizeof(element_type) bytes -- for char it is 1 byte, which basically guarantees no alignment.
thus the array char memory[sizeof(Fred)]
has no alignment guarantees for Fred
.
The proper way of doing it is as follows (C++11):
alignas(Fred) char memory[sizeof(Fred)];
Upvotes: 11
Reputation: 133609
For heap allocations just use std::malloc
which it is guaranteed to allocate memory that is aligned for any type.
For stack allocations, if you have access to C++11, then you can use alignas
as in
alignas(T) uint8_t data[sizeof(T)];
If you don't have access to C++11 then you must fallback to specific compiler attributes as GCC's __attribute__((aligned(N)))
.
Upvotes: 3
Reputation: 477434
Use the alignas
keyword:
alignas(Fred) char buf[sizeof(Fred)];
::new (static_cast<void*>(buf)) Fred;
Or use std::aligned_storage
if you prefer a library wrapper around this construction.
Upvotes: 20