Essential Techniques of Placement New in C++ Development

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&amp; 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—

Leave a Comment