From WeChat Official Account: Program Cat Master
<span>placement new</span> is a special mechanism in C++ that constructs objects at a pre-allocated memory address, without involving any memory allocation operations. It completely bypasses the default heap memory allocation process and is a key mechanism for low-level memory management.
What is<span><span>placement new</span></span>
In simple terms, it allows you to prepare memory yourself and specify the location to construct objects.
Unlike the ordinary <span>new</span> that also allocates memory for you, <span>placement new</span> only does one thing: construct!
Why use<span><span>placement new</span></span>
Many low-level systems, such as memory pools, shared memory, and embedded development,
do not want to frequently allocate and release memory, so they allocate a large block in advance and manually control its usage.
At this point, <span>placement new</span> becomes extremely useful!
Core Features
#include <new> // Required header file
void* memory = std::malloc(sizeof(MyClass)); // 1. Pre-allocate memory
MyClass* obj = new (memory) MyClass(params); // 2. Construct object in this memory
How It Works
No memory allocation: The compiler translates <span>new (addr) T(...)</span> to:
void* __addr = addr; // Accept user-specified address
T* __ptr = static_cast<T*>(__addr);
__ptr->T::T(params); // Directly call constructor at this address
return __ptr;
Corresponding operator new: The low-level call uses a specialized overloaded version:
void* operator new(std::size_t, void* p) noexcept {
return p; // Directly return the input address
}
Key Uses
Custom Memory Management
// Memory pool example
void* pool = allocate_memory(sizeof(MyClass));
MyClass* obj = new (pool) MyClass(); // Directly construct
Stack Object Construction
alignas(MyClass) char buffer[sizeof(MyClass)]; // Stack memory
new (buffer) MyClass(); // Construct on the stack
Shared Memory
void* shared_mem = map_shared_memory("/region1");
new (shared_mem) SharedData(); // Construct object in shared memory
Container Implementation
// Example of internal implementation of std::vector
void* new_storage = allocate(new_capacity);
for (auto& elem : old_items) {
new (new_storage++) T(std::move(elem)); // Move construct to new memory
}
Lifecycle Management
Manual destruction, destructor must be called manually
obj->~MyClass(); // Destructor must be called explicitly
Memory release, cannot use delete.
std::free(memory); // Release original memory (cannot delete obj!)
Low-Level Perspective
; x86_64 example (GCC)
lea rdi, [rbp-32] ; Get memory address (instead of malloc)
call MyClass::MyClass(int) ; Directly call constructor
mov QWORD PTR [rbp-8], rax ; Return object pointer
Common Misuses
// Error 1: Directly delete object created with placement new
MyClass* obj = new (mem) MyClass;
delete obj; // Undefined behavior! Should call destructor + release original memory
// Error 2: Ignoring alignment requirements
char buffer[sizeof(MyClass)];
new (buffer) MyClass(); // May crash due to alignment error (x86 tolerant, ARM fatal)
Interview Tips
Don’t just say “construct objects at specified memory.”
Add these terms: object pool, memory reuse, manual lifecycle control, construction does not handle release, etc.
—END—