21 Language support library [language.support]

21.6 Dynamic memory management [support.dynamic]

The header <new> defines several functions that manage the allocation of dynamic storage in a program. It also defines components for reporting storage management errors.

21.6.1 Header <new> synopsis [new.syn]

namespace std {
  class bad_alloc;
  class bad_array_new_length;
  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;

  // [ptr.launder], pointer optimization barrier
  template <class T> constexpr T* launder(T* p) noexcept;

  // [hardware.interference], hardware interference size
  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;

void* operator new  (std::size_t size, void* ptr) noexcept;
void* operator new[](std::size_t size, void* ptr) noexcept;
void  operator delete  (void* ptr, void*) noexcept;
void  operator delete[](void* ptr, void*) noexcept;

See also: [intro.memory], [basic.stc.dynamic], [expr.new], [expr.delete], [class.free], [memory].

21.6.2 Storage allocation and deallocation [new.delete]

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.

21.6.2.1 Single-object forms [new.delete.single]

void* operator new(std::size_t size); void* operator new(std::size_t size, std::align_val_t alignment);

Effects: The allocation functions called by a new-expression to allocate size bytes of storage. The second form is called for a type with new-extended alignment, and allocates storage with the specified alignment. The first form is called otherwise, and allocates storage suitably aligned to represent any object of that size provided the object's type does not have new-extended alignment.

Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.

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.

Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.

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:

T* p1 = new T;                  // throws bad_­alloc if it fails
T* p2 = new(nothrow) T;         // returns nullptr if it fails

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;

Effects: The deallocation functions called by a delete-expression to render the value of ptr invalid.

Replaceable: A C++ program may define functions with any of these function signatures, and thereby displace the default versions defined by the C++ standard library. If a function without a size parameter is defined, the program should also define the corresponding function with a size parameter. If a function with a size parameter is defined, the program shall also define the corresponding version without the size parameter. [Note: The default behavior below may change in the future, which will require replacing both deallocation functions when replacing the allocation function. end note]

Requires: ptr shall be a null pointer or its value shall represent 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.

Requires: If an implementation has strict pointer safety then ptr shall be a safely-derived pointer.

Requires: If the alignment parameter is not present, ptr shall have been returned by an allocation function without an alignment parameter. If present, the alignment argument shall equal the alignment argument passed to the allocation function that returned ptr. If present, the size argument shall equal 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: 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: See the note in the above Replaceable: 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 <cstdlib>.

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;

Effects: The deallocation functions 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.

Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.

Requires: ptr shall be a null pointer or its value shall represent 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.

Requires: If an implementation has strict pointer safety then ptr shall be a safely-derived pointer.

Requires: If the alignment parameter is not present, ptr shall have been returned by an allocation function without an alignment parameter. If present, the alignment argument shall equal the alignment argument passed to the allocation function that returned ptr.

Default behavior: Calls operator delete(ptr), or operator delete(ptr, alignment), respectively.

21.6.2.2 Array forms [new.delete.array]

void* operator new[](std::size_t size); void* operator new[](std::size_t size, std::align_val_t alignment);

Effects: The allocation functions called by the array form of a new-expression to allocate size bytes of storage. The second form is called for a type with new-extended alignment, and allocates storage with the specified alignment. The first form is called otherwise, and allocates storage suitably aligned to represent any array object of that size or smaller, provided the object's type does not have new-extended alignment.218

Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.

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.

Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.

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;

Effects: The deallocation functions called by the array form of a delete-expression to render the value of ptr invalid.

Replaceable: A C++ program may define functions with any of these function signatures, and thereby displace the default versions defined by the C++ standard library. If a function without a size parameter is defined, the program should also define the corresponding function with a size parameter. If a function with a size parameter is defined, the program shall also define the corresponding version without the size parameter. [Note: The default behavior below may change in the future, which will require replacing both deallocation functions when replacing the allocation function. end note]

Requires: ptr shall be a null pointer or its value shall represent 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[].

Requires: If an implementation has strict pointer safety then ptr shall be a safely-derived pointer.

Requires: If the alignment parameter is not present, ptr shall have been returned by an allocation function without an alignment parameter. If present, the alignment argument shall equal the alignment argument passed to the allocation function that returned ptr. If present, the size argument shall equal 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: 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.

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;

Effects: The deallocation functions 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.

Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.

Requires: ptr shall be a null pointer or its value shall represent 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[].

Requires: If an implementation has strict pointer safety then ptr shall be a safely-derived pointer.

Requires: If the alignment parameter is not present, ptr shall have been returned by an allocation function without an alignment parameter. If present, the alignment argument shall equal the alignment argument passed to the allocation function that returned ptr.

Default behavior: Calls operator delete[](ptr), or operator delete[](ptr, alignment), respectively.

It is not the direct responsibility of operator new[] or operator delete[] to note the repetition count or element size of the array. Those operations are performed elsewhere in the array new and delete expressions. The array new expression, may, however, increase the size argument to operator new[] to obtain space to store supplemental information.

21.6.2.3 Non-allocating forms [new.delete.placement]

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.

void* operator new(std::size_t size, void* ptr) noexcept;

Returns: ptr.

Remarks: Intentionally performs no other action.

[Example: 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]

void* operator new[](std::size_t size, void* ptr) noexcept;

Returns: ptr.

Remarks: Intentionally performs no other action.

void operator delete(void* ptr, void*) noexcept;

Effects: Intentionally performs no action.

Requires: If an implementation has strict pointer safety then ptr shall be a safely-derived pointer.

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.

Requires: If an implementation has strict pointer safety then ptr shall be a safely-derived pointer.

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]).

21.6.2.4 Data races [new.delete.dataraces]

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.

21.6.3 Storage allocation errors [alloc.errors]

21.6.3.1 Class bad_­alloc [bad.alloc]

namespace std {
  class bad_alloc : public exception {
  public:
    bad_alloc() noexcept;
    bad_alloc(const bad_alloc&) noexcept;
    bad_alloc& operator=(const bad_alloc&) noexcept;
    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.

bad_alloc() noexcept;

Effects: Constructs an object of class bad_­alloc.

bad_alloc(const bad_alloc&) noexcept; bad_alloc& operator=(const bad_alloc&) noexcept;

Effects: Copies an object of class bad_­alloc.

const char* what() const noexcept override;

Returns: An implementation-defined ntbs.

Remarks: The message may be a null-terminated multibyte string, suitable for conversion and display as a wstring ([string.classes], [locale.codecvt]).

21.6.3.2 Class bad_­array_­new_­length [new.badlength]

namespace std {
  class bad_array_new_length : public bad_alloc {
  public:
    bad_array_new_length() noexcept;
    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]).

bad_array_new_length() noexcept;

Effects: constructs an object of class bad_­array_­new_­length.

const char* what() const noexcept override;

Returns: An implementation-defined ntbs.

Remarks: The message may be a null-terminated multibyte string, suitable for conversion and display as a wstring ([string.classes], [locale.codecvt]).

21.6.3.3 Type new_­handler [new.handler]

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.

21.6.3.4 set_­new_­handler [set.new.handler]

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.

21.6.3.5 get_­new_­handler [get.new.handler]

new_handler get_new_handler() noexcept;

Returns: The current new_­handler. [Note: This may be a null pointer value. end note]

21.6.4 Pointer optimization barrier [ptr.launder]

template <class T> constexpr T* launder(T* p) noexcept;

Requires: 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 the result are reachable through p (see below).

Returns: A value of type T * that points to X.

Remarks: An invocation of this function may be used in a core constant expression whenever the value of its argument may be used in a core constant expression. A byte of storage is reachable through a pointer value that points to an object Y if it is within the storage occupied by Y, an object that is pointer-interconvertible with Y, or the immediately-enclosing array object if Y is an array element. The program is ill-formed if T is a function type or cv void.

[Note: 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 the type contains const or reference members; in the latter cases, this function can be used to obtain a usable pointer to the new object. See [basic.life]. end note]

[Example:

struct X { const int n; };
X *p = new X{3};
const int a = p->n;
new (p) X{5};                       // p does not point to new object ([basic.life]) because X​::​n is const
const int b = p->n;                 // undefined behavior
const int c = std::launder(p)->n;   // OK

end example]

21.6.5 Hardware interference size [hardware.interference]

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:

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:

struct together {
  atomic<int> dog;
  int puppy;
};
struct kennel {
  // Other data members...
  alignas(sizeof(together)) together pack;
  // Other data members...
};
static_assert(sizeof(together) <= hardware_constructive_interference_size);

end example]