Placement syntax

Short description: C++ syntax for specifying placement of objects in memory

C++ Standard Library

* Input/output
* Strings
* `algorithm`
* `functional`

Containers

* Sequence containers
* Associative containers
* Unordered associative containers

C standard library

* Data types
* Character classification
* Strings
* Mathematics
* File input/output
* Date/time
* Localization
* Memory allocation
* Process control
* Signals
* Alternative tokens
* Miscellaneous headers:
* `<assert.h>`
* `<errno.h>`
* `<setjmp.h>`
* `<stdarg.h>`

* v
* t
* e

The "placement" versions of the `new` and `delete` operators and functions are known as placement `new` and placement `delete`.[1] A `new` expression, placement or otherwise, calls a `new` function, also known as an allocator function, whose name is `operator new`. Similarly, a `delete` expression calls a `delete` function, also known as a deallocator function, whose name is `operator delete`.[2][3]

Any `new` expression that uses the placement syntax is a placement `new` expression, and any `operator new` or `operator delete` function that takes more than the mandatory first parameter (`size_t`) is a placement `new` or placement `delete` function.[4] A placement `new` function takes two input parameters: `size_t` and `void*`.

## Contents

* 1 History
* 2 Expressions
* 3 Functions
* 4 Use
* 4.1 Default placement
* 4.2 Use cases
* 4.3 Preventing exceptions
* 4.4 Custom allocators
* 4.5 Debugging
* 5 Placement delete
* 6 Security
* 7 Notes
* 8 References
* 9 Further reading

## History

In earlier versions of C++, there was no such thing as placement new; instead, developers used explicit assignment to `this` within constructors to achieve similar effect.[5] This practice has been obsolete and removed by C++98[citation needed], and the third edition of Stroustrup's book, The C++ Programming Language, does not mention this technique.

## Expressions

The C++ syntax for a non-placement `new` expression is[2]

`new new-type-id ( optional-initializer-expression-list )`

The placement syntax adds an expression list immediately after the `new` keyword. This expression list is the placement. It can contain any number of expressions.[2][3][6]

`new ( expression-list ) new-type-id ( optional-initializer-expression-list )`

## Functions

The placement `new` functions are overloads of the non-placement `new` functions. The declaration of the non-placement `new` functions, for non-array and array `new` expressions respectively, are:[7][8]

void* operator new(size_t n);
void* operator new[](size_t n);

The C++ Standard Library provides two placement overloads each for these functions. Their declarations are:[7][8]

void* operator new(size_t n, const nothrow_t& t) noexcept;
void* operator new(size_t n, void* p) noexcept;
void* operator new[](size_t n, const nothrow_t& t) noexcept;
void* operator new[](size_t n, void* p) noexcept;

In all of the overloads, the first parameter to the `operator new` function is of type `size_t`, which when the function is called will be passed as an argument specifying the amount of memory, in bytes, to allocate. All of the functions must return type `void*`, which is a pointer to the storage that the function allocates.[2]

There are also placement `delete` functions. They are overloaded versions of the non-placement `delete` functions. The non-placement `delete` functions are declared as:[7][8]

void operator delete(void* p) noexcept;
void operator delete[](void* p) noexcept;

The standard library provides two placement overloads each for these functions. Their declarations are:[7][8]

void operator delete(void* p, const nothrow_t& t) noexcept;
void operator delete(void* p, void* q) noexcept;
void operator delete[](void* p, const nothrow_t& t) noexcept;
void operator delete[](void* p, void* q) noexcept;

In all of the overloads, the first parameter to the `operator delete` function is of type `void*`, which is the address of the storage to deallocate.[2]

Operators `new` and `delete` must reside in the global namespace and cannot have static linkage.[2]

## Use

Placement syntax has four main uses: default placement, preventing exceptions, custom allocators, and debugging.

### Default placement

The placement overloads of `operator new` and `operator delete` that employ an additional `void*` parameter are used for default placement, also known as pointer placement. Their definitions by the standard library, which it is not permitted for a C++ program to replace or override, are:[7][8][9]

void* operator new(size_t n, void* p) noexcept {
return p;

void* operator new[](size_t n, void* p) noexcept {
return p;

void operator delete(void* p, void* q) noexcept {}
void operator delete[](void* p, void* q) noexcept {}

There are various uses for default placement.

Bjarne Stroustrup originally observed, in his book The Design and Evolution of C++, that pointer placement `new` is necessary for hardware that expects a certain object at a specific hardware address. It is also required for the construction of objects that need to reside in a certain memory area, such as an area that is shared between several processors of a multiprocessor computer.[10]

Other uses, however, include calling a constructor directly, something which the C++ language does not otherwise permit.[3]

The C++ language does allow a program to call a destructor directly, and, since it is not possible to destroy the object using a `delete` expression, that is how one destroys an object that was constructed via a pointer placement `new` expression, i.e. `p->~X();`.[11][12]

### Use cases

Placement `new` is used to prevent operator `new` from allocating memory (such as if it has been pre-allocated and one wishes to place the object there), but still construct the object. Examples of typical situations where this may be required are:

* To create objects in memory shared between two different processes.
* To ensure objects are created in non-pageable memory.
* To separate memory allocation from construction e.g. in implementing a `std::vector<T>` (see the `reserve()` method).

The constructor, unlike other functions, is called when there is no object (only memory), and when it finishes executing, the memory is now a fully initialized object. Therefore, the constructor cannot be called on an object, however, it must access (and initialize) non-static members. This makes calling the constructor directly an error. The solution is the placement form of operator `new`.

This operator is implemented as:

void* operator new(size_t count, void* here) noexcept {
return here;

void* operator new[](size_t count, void* here) noexcept {
return here;

### Preventing exceptions

Normally, the (non-placement) `new` functions throw an exception, of type `std::bad_alloc`, if they encounter an error, such as exhaustion of all available memory. This was not how the functions were defined by Stroustrup's Annotated C++ Reference Manual, but was a change made by the standardization committee when the C++ language was standardized. The original behaviour of the functions, which was to return a null pointer when an error occurred, is accessible via placement syntax.[3][4][6]

Usage of this requires header `<new>` from the standard library (or equivalently, module `std`). This header declares the global `std::nothrow` object, which is of type `std::nothrow_t` (also declared in the header), which is used to call the overloaded `new` functions that are declared as taking `const std::nothrow_t&` as their second parameter. For example:[9]

import std;

using std::nothrow;

struct X {
// ...

int main() {
// Call the function operator new(size_t, const nothrow_t&) and (if successful) construct the object.
X* p = new(nothrow) X;
if (p) {
// The storage has been allocated and the constructor called.
delete p;
} else {
// An error has occurred.  No storage has been allocated and no object constructed.

return 0;

### Custom allocators

Placement syntax is also employed for custom allocators. This does not use any of the allocator and deallocator functions from the standard library header `<new>`, but requires that programmers write their own allocation and deallocation functions, overloaded for user-defined types. For example, one could define an arena allocator class as follows:[7][8]

import std;

class Arena {
public:
// ...

void* allocate(size_t n) {
// Allocation method...

void deallocate(void* p) {
// Deallocation method...

Note that arena allocation is provided in the C++ standard library by the `std::pmr::monotonic_buffer_resource` class.[13]

Similarly, define custom placement allocation and deallocation functions as follows:[7][8]

void* operator new(size_t size, Arena& arena) {
return arena.allocate(size);

void operator delete(void* p, Arena& arena) {
arena.deallocate(p);

The program would employ the placement syntax to allocate objects using different instances of the `Arena` class as follows:[7][8]

Arena arena1;
Arena arena2;
X* p1 = new(arena1) X;
X* p2 = new(arena2) X;

Destroying an object whose storage is allocated in such a fashion requires some care. Because there is no placement `delete` expression, one cannot use it to invoke the custom deallocator. One must either write a destruction function that invokes the custom deallocator, or call the placement `delete` function directly, as a function call.[11][7][8]

The former would resemble:[8]

void destroy(X* p, Arena& arena) {
p->~X(); // First invoke the destructor explicitly.
arena.deallocate(p); // Then call the deallocator function directly.

which would be invoked from a program as:

Arena arena;
X* p = new(arena) X;
// ...
destroy(p, arena);

The latter would involve simply writing the destructor invocation and delete function call into the program:[7][14]

Arena arena;
X* p = new(arena) X;
// ...
p->~X(); // First invoke the destructor explicitly.
operator delete(p, arena); // Then call the deallocator function indirectly via operator delete(void*, Arena&).

A common error is to attempt to use a `delete` expression to `delete` the object. This results in the wrong `operator delete` function being called. Dewhurst recommends two strategies for avoiding this error. The first is to ensure that any custom allocators rely upon the standard library's global, non-placement, `operator new`, and are thus nothing more than simple wrappers around the C++ library's memory management. The second is to create `new` and `delete` functions for individual classes, and customize memory management via class function members rather than by using the placement syntax.[14]

### Debugging

Placement `new` can also be used as a simple debugging tool, to enable programs to print the filename and line number of the source code where a memory allocation has failed. This does not require the inclusion of the standard library header `<new>`, but does require the inclusion of a header that declares four placement functions and a macro replacement for the `new` keyword that is used in `new` expressions. For example, such a header would contain:[9][15]

#if defined(DEBUG_NEW)
void* operator new(size_t size, const char* file, int line);
void* operator new[](size_t size, const char* file, int line);
void operator delete(void* p, const char* file, int line);
void operator delete[](void* p, const char* file, int line);
#define New new(__FILE__, __LINE__)
#else
#define New new
#endif

This would be employed in a program as follows:[9][15]

X* p = New X;

The custom-written placement `new` functions would then handle using the supplied file and line number information in the event of an exception. For example:[9][15]

import std;

using std::bad_alloc;
using std::nothrow;

class FailedAllocationException: public bad_alloc {
private:
const char* file;
int line;
public:
FailedAllocationException(const char* file, int line):
bad_alloc(), file{file}, line{line} {}

void* operator new(size_t size, const char* file, int line) {
if (void* p = ::operator new(size, nothrow)) {
return p;

throw FailedAllocationException(file, line);

Since C++26, placement `new` may be used in constexpr contexts.

import std;

template <typename T>
class Box {
private:
alignas(T) unsigned char storage[sizeof(T)];
T* ptr = nullptr;

constexpr void destroy() {
if (active) {
std::destroy_at(ptr); // manually calls the destructor
ptr = nullptr;

public:
constexpr Box() = default;

constexpr ~Box() {
destroy();

template <typename... Args>
constexpr T& emplace(Args&&... args) {
destroy();
T* p = new(static_cast<void*>(storage)) T(std::forward<Args>(args)...);
return *ptr;

constexpr T& get() {
return *ptr;

## Placement delete

As noted above, there is no placement `delete` expression. It is not possible to call any placement `operator delete` function using a `delete` expression.[11][16]

The placement `delete` functions are called from placement `new` expressions. In particular, they are called if the constructor of the object throws an exception. In such a circumstance, in order to ensure that the program does not incur a memory leak, the placement delete functions are called. A placement `new` expression first calls the placement `operator new` function, then calls the constructor of the object upon the raw storage returned from the allocator function. If the constructor throws an exception, it is necessary to deallocate that storage before propagating the exception back to the code that executed the placement `new` expression, and that is the purpose of the placement `delete` functions.[2][4][11][16]

The placement delete function that is called matches the placement `new` function that was invoked by the placement `new` expression. So, for example, if the following code is executed, the placement `delete` function that is called will be `operator delete(void*, const Arena&)`:[2][11][16]

import std;

using std::bad_alloc;

class Arena {
// ...

class X {
public:
X() {
throw bad_alloc("Bad allocation");

void* operator new(size_t n, const Arena& a) {
std::println("Placement new called.");

void operator delete(void* p, const Arena& a) {
std::println("Placement delete called.");

int main() {
Arena arena;
try {
X* p = new(arena) X;
} catch (const bad_alloc& e) {
std::println("Exception caught: {}", e.what());

return 0;

This is why the pointer placement `delete` functions are defined as no-operations by the standard library. Since the pointer placement `new` functions do not allocate any storage, there is no storage to [17] be deallocated in the event of the object's constructor throwing an exception.[11]

If no matching placement delete function exists, no deallocation function is called in the event of an exception being thrown by a constructor within a placement `new` expression. There are also some (older) C++ implementations that do not support placement `delete` (which, like the exception-throwing allocator functions, were an addition made to C++ when it was standardized) at all. In both such situations, an exception being thrown by a constructor when allocating using a custom allocator will result in a memory leak. (In the case of the older C++ implementations, a memory leak will also occur with non-placement `new` expressions.)[4][16]

## Security

Placement `new` expressions are vulnerable to security exploits. In 2011, Kundu and Bertino[17] demonstrated some of the exploits on placement `new`. Some of the attacks are buffer overflow attacks, object overflow, selective stackguard overriding, virtual pointer subterfuge, memory misalignment attacks. In 2015, GCC released a patch[18] based on the findings in.[17]

## Notes

1. ↑ McCluskey 2000
2. ↑ 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 Lischner 2003, pp. 72–73, 128–129, 310, 623–625
3. ↑ 3.0 3.1 3.2 3.3 Lippman 1997, pp. 386–389
4. ↑ 4.0 4.1 4.2 4.3 Meyers 1998
5. ↑ Stroustrup 1991
6. ↑ 6.0 6.1 Loudon 2003, pp. 109–110
7. ↑ 7.00 7.01 7.02 7.03 7.04 7.05 7.06 7.07 7.08 7.09 Vermeir 2001, pp. 113–115
8. ↑ 8.00 8.01 8.02 8.03 8.04 8.05 8.06 8.07 8.08 8.09 Stroustrup 1997, pp. 255–256, 576
9. ↑ 9.0 9.1 9.2 9.3 9.4 Anderson 1998a, pp. 345–356
10. ↑ Stroustrup 1994, pp. 214
11. ↑ 11.0 11.1 11.2 11.3 11.4 11.5 Solter & Kleper 2005, pp. 458–461
12. ↑ Seed & Cooper 2001, pp. 435–436
13. ↑ cppreference.com (7 March 2026). "std::pmr::monotonic_buffer_resource". cppreference.com. https://en.cppreference.com/w/cpp/memory/monotonic_buffer_resource.html.
14. ↑ 14.0 14.1 Dewhurst 2003, pp. 173–176
15. ↑ 15.0 15.1 15.2 Yongwei 2007
16. ↑ 16.0 16.1 16.2 16.3 Anderson 1998b, pp. 631–632
17. ↑ 17.0 17.1 17.2 Kundu, Ashish; Bertino, Elisa (June 2011). "A New Class of Buffer Overflow Attacks". 2011 31st International Conference on Distributed Computing Systems. pp. 730–739. doi:10.1109/ICDCS.2011.63. ISBN 978-1-61284-384-1.
18. ↑ "Martin Sebor - [PING [PATCH] c++/67942 - diagnose placement new buffer overflow"]. https://gcc.gnu.org/legacy-ml/gcc-patches/2015-10/msg02001.html.

## References

* Anderson, Gail (1998a). "Object Storage Management". Navigating C++ and Object-oriented Design. Prentice Hall. ISBN 9780135327487.
* Anderson, Gail (1998b). "Exception Handling". Navigating C++ and Object-oriented Design. Prentice Hall. ISBN 9780135327487.
* Buck, Joe (1997-05-12). "3.4. g++ won't accept the placement new syntax.". Frequently asked questions about the GNU C++ compiler. http://www.desy.de/user/projects/C++/g++faq/placement_new_syntax.html.
* Dewhurst, Stephen C. (2003). "Gotcha #62: Replacing Global New and Delete". C++ Gotchas. Addison-Wesley. ISBN 978-0-321-12518-7. http://informit.com/articles/article.aspx?p=30642&seqNum=3.
* Lischner, Ray (2003). C++ in a Nutshell. O'Reilly. ISBN 9780596002985.
* Lippman, Stanley B. (1997). C++ Gems. Cambridge University Press. ISBN 9780135705810.
* Loudon, Kyle (2003). C++ Pocket Reference. O'Reilly. ISBN 9780596004965.
* "Placement New/Delete". C++ Language and Library. Glen McCluskey & Associates LLC. 2000-06-26. http://glenmccl.com/nd_cmp.htm.
* Meyers, Scott (1998-04-01). "Placement new and placement delete". Dr. Dobb's Journal (United Business Media LLC). http://ddj.com/showArticle.jhtml?documentID=cuj9804meyers&pgno=2.
* Seed, Graham M.; Cooper, Barry J. (2001). An Introduction to Object-oriented Programming in C++ (Second ed.). Springer. ISBN 1-85233-450-9.
* Solter, Nicholas; Kleper, Scott (2005). Professional C++. Wiley. ISBN 9780764574849.
* Stroustrup, Bjarne (July 1991). The C++ Programming Language (2nd ed.). Pearson Education Canada. ISBN 978-0-201-53992-9. https://archive.org/details/cprogramminglang00stro.
* Stroustrup, Bjarne (1994). "Memory Management". Design and Evolution of C++. Addison-Wesley. ISBN 978-0-201-54330-8.
* Stroustrup, Bjarne (1997). The C++ Programming Language (3rd ed.). Addison-Wesley. ISBN 978-0-201-88954-3. https://archive.org/details/cprogramminglang00stro_0.
* Vermeir, Dirk (2001). Multi-paradigm Programming Using C++. Springer. ISBN 9781852334833.
* Yongwei, Wu (2007-12-31). "A Cross-Platform Memory Leak Detector". Wu Yongwei's Programming Page. http://wyw.dcweb.cn/leakage.htm.

## Further reading

* Franek, Frantisek (2004). Memory as a Programming Concept in C and C++. Cambridge University Press. ISBN 978-0-521-52043-0.
* Cline, Marshall (2006-09-25). "11.10: What is "placement new" and why would I use it?". C++ FAQ Lite. http://parashift.com./c++-faq-lite/dtors.html#faq-11.10.
* "C++ new Operator". IBM's Mac OS X compilers. IBM. 2003. http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/topic/com.ibm.vacpp6m.doc/language/ref/clrc05cplr199.htm.
* "The operator new Function". MSDN. Microsoft. http://msdn.microsoft.com/en-us/library/t48aek43.aspx.
* "new Operator (C++)". MSDN. Microsoft. http://msdn.microsoft.com/en-us/library/kewsb8ba.aspx.

0.00

(0 votes)

Original source: https://en.wikipedia.org/wiki/Placement syntax. Read more

|

Retrieved from "https://handwiki.org/wiki/index.php?title=Placement_syntax&oldid=4415634"
*[v]: View this template
*[t]: Discuss this template
*[e]: Edit this template