简体   繁体   中英

Placement-new address alignment

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.

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.

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)];

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))) .

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.

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