Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 442
PoweredByRice Avatar asked Mar 01 '17 01:03

PoweredByRice


People also ask

When to use placement new?

Placement new allows you to construct an object in memory that's already allocated. You may want to do this for optimization when you need to construct multiple instances of an object, and it is faster not to re-allocate memory each time you need a new instance.

Does placement New allocate memory?

Because placement new does not allocate memory, you should not use delete to deallocate objects created with the placement syntax. You can only delete the entire memory pool ( delete whole ). In the example, you can keep the memory buffer but destroy the object stored in it by explicitly calling a destructor.


2 Answers

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.

like image 140
Kerrek SB Avatar answered Oct 22 '22 23:10

Kerrek SB


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)];
like image 40
akappa Avatar answered Oct 23 '22 00:10

akappa