C++ for Systems Programmers

placement new

Normally, new does two jobs at once: it allocates memory from the heap and then constructs an object in it. But sometimes you already have the memory — a buffer you allocated yourself, a slot in a memory pool, a region of shared memory — and you only want the second job, the construction, done right there. Placement new is the form of new that skips allocation and instead builds an object at an address you hand it.

The syntax is new (address) Type(args...): you pass a pointer to already-obtained, suitably sized and aligned storage inside parentheses, and new constructs a Type object exactly at that location, running its constructor but allocating nothing. The flip side is that, because placement new did not allocate, you must not delete the object — there is no matching deallocation to pair with it. Instead you call the destructor explicitly (p->~Type()) when you are done, and separately free the underlying buffer however you obtained it. This manual two-step — explicit construct, explicit destruct — is the price of decoupling object lifetime from memory allocation.

Why it matters: placement new is the foundation of how containers and allocators actually work. std::vector, for instance, allocates a raw buffer up front and then placement-news each element into it as you push_back, which is exactly how it can reserve capacity without constructing objects it doesn't yet hold. It is also essential for memory pools, std::optional, std::variant, and serialization. The honest dangers are sharp: the storage must be correctly aligned for the type (misalignment is undefined behavior), you are fully responsible for calling the destructor exactly once, and forgetting it leaks any resources the object owned even though the raw memory itself is freed. This is low-level, error-prone machinery — most code should let the standard containers do it for you.

alignas(Widget) std::byte buf[sizeof(Widget)]; Widget* w = new (buf) Widget(args); /* use w */ w->~Widget(); // explicit destroy; no delete

The object is constructed inside an existing, correctly aligned buffer; you must call the destructor by hand and never delete it.

Placement new allocates nothing, so it has no matching delete: pairing it with delete is undefined behavior. The buffer must also satisfy the type's alignment requirement — building a Widget in under-aligned bytes is UB, which the standard imposes no requirements on, so the optimizer may assume it never happens.

Also called
construct-in-placein-place construction定位 new