operator new, operator new[]
Defined in header <new>
|
||
replaceable allocation functions [[nodiscard]] (since c++20) |
||
void* operator new ( std::size_t count ); |
(1) | |
void* operator new[]( std::size_t count ); |
(2) | |
void* operator new ( std::size_t count, std::align_val_t al); |
(3) | (since C++17) |
void* operator new[]( std::size_t count, std::align_val_t al); |
(4) | (since C++17) |
replaceable non-throwing allocation functions [[nodiscard]] (since c++20) |
||
void* operator new ( std::size_t count, const std::nothrow_t& tag); |
(5) | |
void* operator new[]( std::size_t count, const std::nothrow_t& tag); |
(6) | |
void* operator new ( std::size_t count, std::align_val_t al, const std::nothrow_t&); |
(7) | (since C++17) |
void* operator new[]( std::size_t count, std::align_val_t al, const std::nothrow_t&); |
(8) | (since C++17) |
non-allocating placement allocation functions [[nodiscard]] (since c++20) |
||
void* operator new ( std::size_t count, void* ptr ); |
(9) | |
void* operator new[]( std::size_t count, void* ptr ); |
(10) | |
user-defined placement allocation functions |
||
void* operator new ( std::size_t count, user-defined-args... ); |
(11) | |
void* operator new[]( std::size_t count, user-defined-args... ); |
(12) | |
void* operator new ( std::size_t count, std::align_val_t al, user-defined-args... ); |
(13) | (since C++17) |
void* operator new[]( std::size_t count, std::align_val_t al, user-defined-args... ); |
(14) | (since C++17) |
class-specific allocation functions |
||
void* T::operator new ( std::size_t count ); |
(15) | |
void* T::operator new[]( std::size_t count ); |
(16) | |
void* T::operator new ( std::size_t count, std::align_val_t al ); |
(17) | (since C++17) |
void* T::operator new[]( std::size_t count, std::align_val_t al ); |
(18) | (since C++17) |
class-specific placement allocation functions |
||
void* T::operator new ( std::size_t count, user-defined-args... ); |
(19) | |
void* T::operator new[]( std::size_t count, user-defined-args... ); |
(20) | |
void* T::operator new ( std::size_t count, std::align_val_t al, user-defined-args... ); |
(21) | (since C++17) |
void* T::operator new[]( std::size_t count, std::align_val_t al, user-defined-args... ); |
(22) | (since C++17) |
Allocates requested number of bytes. These allocation functions are called by new-expressions to allocate memory in which new object would then be initialized. They may also be called using regular function call syntax.
count
bytes from free store. In case of failure, the standard library implementation calls the function pointer returned by std::get_new_handler and repeats allocation attempts until new handler does not return or becomes a null pointer, at which time it throws std::bad_alloc. This function is required to return a pointer suitably aligned to hold an object of any fundamental alignment.__STDCPP_DEFAULT_NEW_ALIGNMENT__
__STDCPP_DEFAULT_NEW_ALIGNMENT__
__STDCPP_DEFAULT_NEW_ALIGNMENT__
. The standard library implementation calls the version (3) and returns a null pointer on failure instead of propagating the exception.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. The standard library implementation calls the version (4) and returns a null pointer on failure instead of propagating the exception.ptr
unmodified.ptr
unmodified.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. If a class-specific version is defined ((15) or (17)), it is called instead. If neither class-specific nor global alignment-aware (this one) placement form is provided, alignment-unaware placement form (11) is looked up instead.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. If a class-specific version ((16) or (18)) is defined, it is called instead. If neither class-specific nor global alignment-aware (this one) placement form is provided, alignment-unaware placement form (12) is looked up instead.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. If this overload is not provided, but allocator-unaware member form (15) is, allocator-unaware member overload is called instead.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. If this overload is not provided, but allocator-unaware member form (16) is, allocator-unaware member overload is called instead.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. If this overload is not provided, but allocator-unaware member form (19) is, allocator-unaware member overload is called instead.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. If this overload is not provided, but allocator-unaware member form (20) is, allocator-unaware member overload is called instead.Parameters
count | - | number of bytes to allocate |
ptr | - | pointer to a memory area to initialize the object at |
tag | - | disambiguation tag used to select non-throwing overloads |
al | - | alignment to use. The behavior is undefined if this is not a valid alignment value |
Return value
non-null pointer to suitably aligned memory of size at least size
Exceptions
(none) | (until C++11) |
noexcept specification: noexcept |
(since C++11) |
Global replacements
The versions (1-4) are implicitly declared in each translation unit even if the <new>
header is not included. Versions (1-8) are replaceable: a user-provided non-member function with the same signature defined anywhere in the program, in any source file, replaces the default version. Its declaration does not need to be visible.
The behavior is undefined if more than one replacement is provided in the program for any of the replaceable allocation function, or if a replacement is defined with the inline
specifier. The program is ill-formed if a replacement is defined in namespace other than global namespace, or if it is defined as a static non-member function at global scope.
The standard library implementations of the nothrow versions (5-8) directly calls the corresponding throwing versions (1-4). The standard library implementation of the throwing array versions (2,4) directly calls the corresponding single-object version (1,3). Thus, replacing the throwing single object allocation functions is sufficient to handle all allocations. | (since C++11) |
#include <cstdio> #include <cstdlib> // replacement of a minimal set of functions: void* operator new(std::size_t sz) { std::printf("global op new called, size =%zu\n",sz); return std::malloc(sz); } void operator delete(void* ptr) noexcept { std::puts("global op delete called"); std::free(ptr); } int main() { int* p1 = new int; delete p1; int* p2 = new int[10]; // guaranteed to call the replacement in C++11 delete[] p2; }
Possible output:
global op new called, size = 4 global op delete called global op new called, size = 40 global op delete called
Overloads of operator new
and operator new[]
with additional user-defined parameters ("placement forms", versions (11-14)) may be declared at global scope as usual, and are called by the matching placement forms of new-expressions.
The standard library's non-allocating placement forms of operator new (9-10) cannot be replaced and can only be customized if the placement new-expression did not use the ::new
syntax, by providing a class-specific placement new (19,20) with matching signature: void* T::operator new(size_t, void*)
or void* T::operator new[](size_t, void*)
.
The placement form |
(since C++14) |
Class-specific overloads
Both single-object and array allocation functions may be defined as public static member functions of a class (versions (15-18)). If defined, these allocation functions are called by new-expressions to allocate memory for single objects and arrays of this class, unless the new expression used the form ::new
which bypasses class-scope lookup. The keyword static
is optional for these functions: whether used or not, the allocation function is a static member function.
The new expression looks for appropriate allocation function's name firstly in the class scope, and after that in the global scope. Note, that as per name lookup rules, any allocation functions declared in class scope hides all global allocation functions for the new-expressions that attempt to allocate objects of this class.
When allocating objects and arrays of objects whose alignment exceeds |
(since C++17) |
#include <iostream> // class-specific allocation functions struct X { static void* operator new(std::size_t sz) { std::cout << "custom new for size " << sz << '\n'; return ::operator new(sz); } static void* operator new[](std::size_t sz) { std::cout << "custom new for size " << sz << '\n'; return ::operator new(sz); } }; int main() { X* p1 = new X; delete p1; X* p2 = new X[10]; delete[] p2; }
Possible output:
custom new for size 1 custom new for size 10
Overloads of operator new
and operator new[]
with additional user-defined parameters ("placement forms"), may also be defined as class members (19-22)). When the placement new expression with the matching signature looks for the corresponding allocation function to call, it begins at class scope before examining the global scope, and if the class-specific placement new is provided, it is called.
When allocating objects and arrays of objects whose alignment exceeds |
(since C++17) |
#include <stdexcept> #include <iostream> struct X { X() { throw std::runtime_error(""); } // custom placement new static void* operator new(std::size_t sz, bool b) { std::cout << "custom placement new called, b = " << b << '\n'; return ::operator new(sz); } // custom placement delete static void operator delete(void* ptr, bool b) { std::cout << "custom placement delete called, b = " << b << '\n'; ::operator delete(ptr); } }; int main() { try { X* p1 = new (true) X; } catch(const std::exception&) { } }
Output:
custom placement new called, b = 1 custom placement delete called, b = 1
If class-level operator new
is a template function, it must have the return type of void*
, the first argument std::size_t
, and it must have two or more parameters. In other words, only placement forms can be templates.
Notes
Even though the non-allocating placement new (9,10) cannot be replaced, a function with the same signature may be defined at class scope as described above. In addition, global overloads that look like placement new but take a non-void pointer type as the second argument are allowed, so the code that wants to ensure that the true placement new is called (e.g. std::allocator::construct), must use ::new
and also cast the pointer to void*
.
The following functions are required to be thread-safe:
Calls to these functions that allocate or deallocate a particular unit of storage occur in a single total order, and each such deallocation call happens-before the next allocation (if any) in this order. |
(since C++11) |
It is unspecified whether library versions of operator new
make any calls to std::malloc or std::aligned_alloc (since C++17)
Example
Custom placement forms of operator new can be used for any purpose, for example, to fill the allocated array
#include <iostream> #include <algorithm> void* operator new[](std::size_t sz, char c) { void* p = operator new[](sz); std::fill_n(reinterpret_cast<char*>(p), sz, c); return p; } int main() { char* p = new('*') char[6]; p[5] = '\0'; std::cout << p << '\n'; delete[] p; }
Output:
*****
See also
deallocation functions (function) | |
(C++11) |
obtains the current new handler (function) |
registers a new handler (function) | |
(deprecated in C++17)(removed in C++20) |
obtains uninitialized storage (function template) |
allocates memory (function) | |
(C++17) |
allocates aligned memory (function) |
References
- C++11 standard (ISO/IEC 14882:2011):
- 18.6 Dynamic memory management [support.dynamic]