17 Language support library [support]
17.6.3 Storage allocation and deallocation [new.delete]
The header  defines several
functions that manage the allocation of dynamic storage in a program
.It also defines components for reporting storage management errors
.
namespace std {
  
  class bad_alloc;
  class bad_array_new_length;
  struct destroying_delete_t {
    explicit destroying_delete_t() = default;
  };
  inline constexpr destroying_delete_t destroying_delete{};
  
  enum class align_val_t : size_t {};
  struct nothrow_t { explicit nothrow_t() = default; };
  extern const nothrow_t nothrow;
  using new_handler = void (*)();
  new_handler get_new_handler() noexcept;
  new_handler set_new_handler(new_handler new_p) noexcept;
  
  template<class T> constexpr T* launder(T* p) noexcept;
  
  inline constexpr size_t hardware_destructive_interference_size = implementation-defined;
  inline constexpr size_t hardware_constructive_interference_size = implementation-defined;
}
void* operator new(std::size_t size);
void* operator new(std::size_t size, std::align_val_t alignment);
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;
void operator delete(void* ptr) noexcept;
void operator delete(void* ptr, std::size_t size) noexcept;
void operator delete(void* ptr, std::align_val_t alignment) noexcept;
void operator delete(void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
void operator delete(void* ptr, const std::nothrow_t&) noexcept;
void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size);
void* operator new[](std::size_t size, std::align_val_t alignment);
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size, std::align_val_t alignment,
                     const std::nothrow_t&) noexcept;
void operator delete[](void* ptr) noexcept;
void operator delete[](void* ptr, std::size_t size) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment) noexcept;
void operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;
constexpr void* operator new  (std::size_t size, void* ptr) noexcept;
constexpr void* operator new[](std::size_t size, void* ptr) noexcept;
void operator delete  (void* ptr, void*) noexcept;
void operator delete[](void* ptr, void*) noexcept;
Except where otherwise specified, the provisions of 
[basic.stc.dynamic]
apply to the library versions of 
operator new and 
operator
delete.If the value of an alignment argument
passed to any of these functions
is not a valid alignment value,
the behavior is undefined
.On freestanding implementations,
it is 
implementation-defined
whether the default versions of the replaceable global allocation functions
satisfy the required behaviors
described in 
[new.delete.single] and 
[new.delete.array].[
Note 1: 
A freestanding implementation's default versions of
the replaceable global allocation functions
can cause undefined behavior when invoked
.During constant evaluation,
the behaviors of those default versions are irrelevant,
as those calls are omitted (
[expr.new])
. — 
end note]
Recommended practice: If any of the default versions of the replaceable global allocation functions
meet the requirements of a hosted implementation, they all should
. void* operator new(std::size_t size);
void* operator new(std::size_t size, std::align_val_t alignment);
 The second form is called for a type with new-extended alignment, and
the first form is called otherwise
. Required behavior: Return a non-null pointer to suitably aligned storage (
[basic.stc.dynamic]),
or else throw a
bad_alloc
exception
.  This requirement is binding on any replacement versions of these functions
.Default behavior: 
- Executes a loop:
Within the loop, the function first attempts to allocate the requested storage .
- Whether the attempt involves a call to the C standard library functions
 malloc-  or  aligned_alloc- 
is unspecified .
- Returns a pointer to the allocated storage if the attempt is successful .
- Otherwise, if the
current  new_handler-  ( [get.new.handler]- ) is
a null pointer value, throws
 bad_alloc.
- Otherwise, the function calls the current
 new_handler-  function .
- If the called function returns, the loop repeats .
- The loop terminates when an attempt to allocate the requested storage is
successful or when a called
 new_handler- 
function does not return .
 void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;
Effects: Same as above, except that these are called by a placement version of a
new-expression
when a C++ program prefers a null pointer result as an error indication,
instead of a
bad_alloc
exception
. Required behavior: Return a non-null pointer to suitably aligned storage (
[basic.stc.dynamic]),
or else return a null pointer
.  Each of these nothrow versions of
operator new
returns a pointer obtained as if
acquired from the (possibly replaced)
corresponding non-placement function
.This requirement is binding on any replacement versions of these functions
.Default behavior: Calls 
operator new(size),
or 
operator new(size, alignment),
respectively
.  If the call returns normally,
returns the result of that call
.Otherwise, returns a null pointer
.[
Example 1: 
T* p1 = new T;                  
T* p2 = new(nothrow) T;         
 — 
end example]
void operator delete(void* ptr) noexcept;
void operator delete(void* ptr, std::size_t size) noexcept;
void operator delete(void* ptr, std::align_val_t alignment) noexcept;
void operator delete(void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
Preconditions: 
ptr is a null pointer or
its value represents the address of
a block of memory allocated by
an earlier call to a (possibly replaced)
operator new(std::size_t)
or
operator new(std::size_t, std::align_val_t)
which has not been invalidated by an intervening call to
operator delete. If the 
alignment parameter is not present,
ptr was returned by an allocation function
without an 
alignment parameter
.If present, the 
alignment argument
is equal to the 
alignment argument
passed to the allocation function that returned 
ptr.If present, the 
size argument
is equal to the 
size argument
passed to the allocation function that returned 
ptr.Required behavior: A call to an 
operator delete
with a 
size parameter
may be changed to
a call to the corresponding 
operator delete
without a 
size parameter,
without affecting memory allocation
.  [
Note 1: 
A conforming implementation is for
operator delete(void* ptr, std::size_t size) to simply call
operator delete(ptr). — 
end note]
Default behavior: The functions that have a 
size parameter
forward their other parameters
to the corresponding function without a 
size parameter
.  [
Note 2: 
See the note in the below 
Remarks: paragraph
. — 
end note]
Default behavior: If 
ptr is null, does nothing
.  Otherwise, reclaims the
storage allocated by the earlier call to 
operator new.Remarks: It is unspecified under what conditions part or all of such
reclaimed storage will be allocated by subsequent
calls to
operator new
or any of
aligned_alloc,
calloc,
malloc,
or
realloc,
declared in 
.   If a replacement function
without a 
size parameter
is defined by the program,
the program should also define the corresponding
function with a 
size parameter
.If a replacement function
with a 
size parameter
is defined by the program,
the program shall also define the corresponding
version without the 
size parameter
.[
Note 3: 
The default behavior above might change in the future,
which will require replacing both deallocation functions
when replacing the allocation function
. — 
end note]
void operator delete(void* ptr, const std::nothrow_t&) noexcept;
void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;
Preconditions: 
ptr is a null pointer or
its value represents the address of
a block of memory allocated by
an earlier call to a (possibly replaced)
operator new(std::size_t)
or
operator new(std::size_t, std::align_val_t)
which has not been invalidated by an intervening call to
operator delete. If the 
alignment parameter is not present,
ptr was returned by an allocation function
without an 
alignment parameter
.If present, the 
alignment argument
is equal to the 
alignment argument
passed to the allocation function that returned 
ptr.Effects: The
deallocation functions (
[basic.stc.dynamic.deallocation])
called by the implementation
to render the value of 
ptr invalid
when the constructor invoked from a nothrow
placement version of the 
new-expression throws an exception
. Default behavior: Calls 
operator delete(ptr),
or 
operator delete(ptr, alignment),
respectively
. void* operator new[](std::size_t size);
void* operator new[](std::size_t size, std::align_val_t alignment);
 The second form is called for a type with new-extended alignment, and
the first form is called otherwise
. Required behavior: Same as for
the corresponding single-object forms
.  This requirement is binding on any replacement versions of these functions
.Default behavior: Returns
operator new(size),
or
operator new(size, alignment),
respectively
. void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;
Effects: Same as above, except that these are called by a placement version of a
new-expression
when a C++ program prefers a null pointer result as an error indication,
instead of a
bad_alloc
exception
. Required behavior: Return a non-null pointer to suitably aligned storage (
[basic.stc.dynamic]),
or else return a null pointer
.  Each of these nothrow versions of
operator new[]
returns a pointer obtained as if
acquired from the (possibly replaced)
corresponding non-placement function
.This requirement is binding on any replacement versions of these functions
.Default behavior: Calls 
operator new[](size),
or 
operator new[](size, alignment),
respectively
.  If the call returns normally,
returns the result of that call
.Otherwise, returns a null pointer
.void operator delete[](void* ptr) noexcept;
void operator delete[](void* ptr, std::size_t size) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment) noexcept;
void operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
Preconditions: 
ptr is a null pointer or
its value represents the address of
a block of memory allocated by
an earlier call to a (possibly replaced)
operator new[](std::size_t)
or
operator new[](std::size_t, std::align_val_t)
which has not been invalidated by an intervening call to
operator delete[]. If the 
alignment parameter is not present,
ptr was returned by an allocation function
without an 
alignment parameter
.If present, the 
alignment argument
is equal to the 
alignment argument
passed to the allocation function that returned 
ptr.If present, the 
size argument
is equal to the 
size argument
passed to the allocation function that returned 
ptr.Required behavior: A call to an 
operator delete[]
with a 
size parameter
may be changed to
a call to the corresponding 
operator delete[]
without a 
size parameter,
without affecting memory allocation
.  [
Note 1: 
A conforming implementation is for
operator delete[](void* ptr, std::size_t size) to simply call
operator delete[](ptr). — 
end note]
Default behavior: The functions that have a 
size parameter
forward their other parameters
to the corresponding function without a 
size parameter
.  The functions that do not have a 
size parameter
forward their parameters
to the corresponding 
operator delete (single-object) function
. If a replacement function
without a 
size parameter
is defined by the program,
the program should also define the corresponding
function with a 
size parameter
.If a replacement function
with a 
size parameter
is defined by the program,
the program shall also define the corresponding
version without the 
size parameter
.[
Note 2: 
The default behavior above might change in the future,
which will require replacing both deallocation functions
when replacing the allocation function
. — 
end note]
 void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;
Preconditions: 
ptr is a null pointer or
its value represents the address of
a block of memory allocated by
an earlier call to a (possibly replaced)
operator new[](std::size_t)
or
operator new[](std::size_t, std::align_val_t)
which has not been invalidated by an intervening call to
operator delete[]. If the 
alignment parameter is not present,
ptr was returned by an allocation function
without an 
alignment parameter
.If present, the 
alignment argument
is equal to the 
alignment argument
passed to the allocation function that returned 
ptr.Effects: The
deallocation functions (
[basic.stc.dynamic.deallocation])
called by the implementation
to render the value of 
ptr invalid
when the constructor invoked from a nothrow
placement version of the array 
new-expression throws an exception
. Default behavior: Calls 
operator delete[](ptr),
or 
operator delete[](ptr, alignment),
respectively
. These functions are reserved; a C++ program may not define functions that displace
the versions in the C++ standard library (
[constraints])
.The provisions of 
[basic.stc.dynamic] do not apply to these reserved
placement forms of 
operator new and 
operator delete.constexpr void* operator new(std::size_t size, void* ptr) noexcept;
Remarks: Intentionally performs no other action
. [
Example 1: 
This can be useful for constructing an object at a known address:
void* place = operator new(sizeof(Something));
Something* p = new (place) Something();
 — 
end example]
constexpr void* operator new[](std::size_t size, void* ptr) noexcept;
Remarks: Intentionally performs no other action
. void operator delete(void* ptr, void*) noexcept;
Effects: Intentionally performs no action
. Remarks: Default function called when any part of the initialization in a
placement 
new-expression that invokes the library's
non-array placement operator new
terminates by throwing an exception (
[expr.new])
. void operator delete[](void* ptr, void*) noexcept;
Effects: Intentionally performs no action
. Remarks: Default function called when any part of the initialization in a
placement 
new-expression that invokes the library's
array placement operator new
terminates by throwing an exception (
[expr.new])
. For purposes of determining the existence of data races, the library versions
of 
operator new, user replacement versions of global 
operator new,
the C standard library functions
aligned_alloc, 
calloc, and 
malloc,
the library
versions of 
operator delete, user replacement
versions of 
operator delete, the C standard library function
free, and the C standard library function 
realloc shall not
introduce a data race (
[res.on.data.races])
.Calls to these functions that allocate or deallocate a particular unit
of storage shall occur in a single total order, and each such deallocation call
shall 
happen before
the next allocation (if any) in this order
.
namespace std {
  class bad_alloc : public exception {
  public:
    
    constexpr const char* what() const noexcept override;
  };
}
 The class
bad_alloc
defines the type of objects thrown as
exceptions by the implementation to report a failure to allocate storage
.constexpr const char* what() const noexcept override;
Returns: An 
implementation-defined 
ntbs. 
namespace std {
  class bad_array_new_length : public bad_alloc {
  public:
    
    constexpr const char* what() const noexcept override;
  };
}
 The class 
bad_array_new_length defines the type of objects thrown as
exceptions by the implementation to report an attempt to allocate an array of size
less than zero or
greater than an 
implementation-defined limit (
[expr.new])
.constexpr const char* what() const noexcept override;
Returns: An 
implementation-defined 
ntbs. using new_handler = void (*)();
The type of a
handler function
to be called by
operator new()
or
operator new[]() (
[new.delete]) when they cannot satisfy a request for additional storage
.Required behavior: A 
new_handler shall perform one of the following:
- make more storage available for allocation and then return;
- throw an exception of type
bad_alloc
or a class derived from
bad_alloc;
- terminate execution of the program without returning to the caller. 
 new_handler set_new_handler(new_handler new_p) noexcept;
Effects: Establishes the function designated by 
new_p as the current
new_handler. Returns: The previous 
new_handler. Remarks: The initial 
new_handler is a null pointer
. new_handler get_new_handler() noexcept;
Returns: The current 
new_handler.  [
Note 1: 
This can be a null pointer value
. — 
end note]
template<class T> constexpr T* launder(T* p) noexcept;
Mandates: 
!is_function_v<T> && !is_void_v<T> is 
true. Preconditions: 
p represents the address 
A of a byte in memory
.  An object 
X that is within its 
lifetime
and whose type is 
similar to 
T
is located at the address 
A.All bytes of storage that would be
reachable through (
[basic.compound]) the result
are reachable through 
p.Returns: A value of type 
T* that points to 
X. Remarks: An invocation of this function
may be used in a core constant expression
if and only if the (converted) value of its argument
may be used in place of the function invocation
. [
Note 1: 
If a new object is created
in storage occupied by an existing object of the same type,
a pointer to the original object
can be used to refer to the new object
unless its complete object is a const object or it is a base class subobject;
in the latter cases,
this function can be used to obtain a usable pointer to the new object
. — 
end note]
[
Example 1: 
struct X { int n; };
const X *p = new const X{3};
const int a = p->n;
new (const_cast<X*>(p)) const X{5}; 
const int b = p->n;                 
const int c = std::launder(p)->n;   
 — 
end example]
inline constexpr size_t hardware_destructive_interference_size = implementation-defined;
This number is the minimum recommended offset
between two concurrently-accessed objects
to avoid additional performance degradation due to contention
introduced by the implementation
.It shall be at least 
alignof(max_align_t).[
Example 1: 
struct keep_apart {
  alignas(hardware_destructive_interference_size) atomic<int> cat;
  alignas(hardware_destructive_interference_size) atomic<int> dog;
};
 — 
end example]
inline constexpr size_t hardware_constructive_interference_size = implementation-defined;
This number is the maximum recommended size of contiguous memory
occupied by two objects accessed with temporal locality by concurrent threads
.It shall be at least 
alignof(max_align_t).[
Example 2: 
struct together {
  atomic<int> dog;
  int puppy;
};
struct kennel {
  
  alignas(sizeof(together)) together pack;
  
};
static_assert(sizeof(together) <= hardware_constructive_interference_size);
 — 
end example]