Why using placement new operator in C++ is a bad thing?

in #programming4 years ago

Normal new operator in C++ allocates memory and then calls the class constructor.
Placement new operator uses passed in memory buffer and calls class constructor to initialize that memory.
Memory buffer is class member with type "char[sizeof(class)]", where class is any C++ class or struct.

In my opinion placement new should not be used when the class has custom move constructor and/or move assignment operator that dereferences memory buffer of class member. If the code would be using normal new operator for the class member, it could just move the pointer instead of using reinterpret_cast to convert the pointer to memory buffer to pointer to the class member, and dereferencing addresses of both the source and destination class members to pass the class member reference using std::move().

Dereferencing preallocated memory buffer also violates strict aliasing rules of the compiler as compiler can't know if the memory region is used with multiple pointers as the memory locations might not seem to overlap even if more than one pointer is used to modify same class member. Compiler can only know if the offset from start of class is known at the time of compilation. This means the correctly-typed pointer has to be stored in a non-temporary variable.

When preallocated memory buffer is used inside a union, the size of the union member can be a lot larger than size of shortest member type; when pointer and normal new operator is used, the size of union is at most 4 or 8 bytes. This means if the class containing the union is used several times in the code, memory consumption can increase exponentially even when the memory buffers are not used.