18 Language support library [language.support]

18.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.

Header <new> synopsis

namespace std {
  class bad_alloc;
  class bad_array_new_length;
  struct nothrow_t {};
  extern const nothrow_t nothrow;
  typedef void (*new_handler)();
  new_handler get_new_handler() noexcept;
  new_handler set_new_handler(new_handler new_p) noexcept;
}

void* operator new(std::size_t size);
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
void  operator delete(void* ptr) noexcept;
void  operator delete(void* ptr, const std::nothrow_t&) noexcept;
void  operator delete(void* ptr, std::size_t size) noexcept;
void  operator delete(void* ptr, std::size_t size,
                      const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size);
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
void  operator delete[](void* ptr) noexcept;
void  operator delete[](void* ptr, const std::nothrow_t&) noexcept;
void  operator delete[](void* ptr, std::size_t size) noexcept;
void  operator delete[](void* ptr, std::size_t size,
                        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].

18.6.1 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.

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

void* operator new(std::size_t size);

Effects: The allocation function ([basic.stc.dynamic.allocation]) called by a new-expression ([expr.new]) to allocate size bytes of storage suitably aligned to represent any object of that size.

Replaceable: a C++ program may define a function with this function signature that displaces the default version 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 a replacement version of this function.

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 Standard C library function malloc 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 ([new.handler]). 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;

Effects: Same as above, except that it is 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 a function with this function signature that displaces the default version 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. This nothrow version of operator new returns a pointer obtained as if acquired from the (possibly replaced) ordinary version. This requirement is binding on a replacement version of this function.

Default behavior: Calls operator new(size). 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;

Effects: The deallocation function ([basic.stc.dynamic.deallocation]) called by a delete-expression to render the value of ptr invalid.

Replaceable: a C++ program may define a function with signature void operator delete(void* ptr) noexcept that displaces the default version defined by the C++ standard library. If this function (without size parameter) is defined, the program should also define void operator delete(void* ptr, std::size_t size) noexcept. If this function with size parameter is defined, the program shall also define the 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 be a value returned by an earlier call to the (possibly replaced) operator new(std::size_t) or operator new(std::size_t,const std::nothrow_t&) which has not been invalidated by an intervening call to operator delete(void*).

Requires: If an implementation has strict pointer safety ([basic.stc.dynamic.safety]) then ptr shall be a safely-derived pointer.

Requires: If present, the std::size_t size argument shall equal the size argument passed to the allocation function that returned ptr.

Required behavior: Calls to operator delete(void* ptr, std::size_t size) may be changed to calls to operator delete(void* ptr) 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 function operator delete(void* ptr, std::size_t size) calls operator delete(ptr). [ 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 calloc, malloc, or realloc, declared in <cstdlib>.

void operator delete(void* ptr, const std::nothrow_t&) noexcept; void operator delete(void* ptr, std::size_t size, const std::nothrow_t&) noexcept;

Effects: The deallocation function ([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.

Replaceable: a C++ program may define a function with signature void operator delete(void* ptr, const std::nothrow_t&) noexcept that displaces the default version defined by the C++ standard library. If this function (without size parameter) is defined, the program should also define void operator delete(void* ptr, std::size_t size, const std::nothrow_t&) noexcept. If this function with size parameter is defined, the program shall also define the 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: If an implementation has strict pointer safety ([basic.stc.dynamic.safety]) then ptr shall be a safely-derived pointer.

Requires: If present, the std::size_t size argument must equal the size argument passed to the allocation function that returned ptr.

Required behavior: Calls to operator delete(void* ptr, std::size_t size, const std::nothrow_t&) may be changed to calls to operator delete(void* ptr, const std::nothrow_t&) without affecting memory allocation. [ Note: A conforming implementation is for operator delete(void* ptr, std::size_t size, const std::nothrow_t&) to simply call operator delete(void* ptr, const std::nothrow_t&).  — end note ]

Default behavior: operator delete(void* ptr, std::size_t size, const std::nothrow_t&) calls operator delete(ptr, std::nothrow), and operator delete(void* ptr, const std::nothrow_t&) calls operator delete(ptr).

18.6.1.2 Array forms [new.delete.array]

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

Effects: The allocation function ([basic.stc.dynamic.allocation]) called by the array form of a new-expression ([expr.new]) to allocate size bytes of storage suitably aligned to represent any array object of that size or smaller.227

Replaceable: a C++ program can define a function with this function signature that displaces the default version defined by the C++ standard library.

Required behavior: Same as for operator new(std::size_t). This requirement is binding on a replacement version of this function.

Default behavior: Returns operator new(size).

void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;

Effects: Same as above, except that it is 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 can define a function with this function signature that displaces the default version defined by the C++ standard library.

Required behavior: Return a non-null pointer to suitably aligned storage ([basic.stc.dynamic]), or return a null pointer. This requirement is binding on a replacement version of this function.

Default behavior: Calls operator new[](size). 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;

Effects: The deallocation function ([basic.stc.dynamic.deallocation]) called by the array form of a delete-expression to render the value of ptr invalid.

Replaceable: a C++ program can define a function with signature void operator delete[](void* ptr) noexcept that displaces the default version defined by the C++ standard library. If this function (without size parameter) is defined, the program should also define void operator delete[](void* ptr, std::size_t size) noexcept. If this function with size parameter is defined, the program shall also define the 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 be the value returned by an earlier call to operator new[](std::size_t) or operator new[](std::size_t,const std::nothrow_t&) which has not been invalidated by an intervening call to operator delete[](void*).

Requires: If present, the std::size_t size argument must equal the size argument passed to the allocation function that returned ptr.

Required behavior: Calls to operator delete[](void* ptr, std::size_t size) may be changed to calls to operator delete[](void* ptr) without affecting memory allocation. [ Note: A conforming implementation is for operator delete[](void* ptr, std::size_t size) to simply call operator delete[](void* ptr).  — end note ]

Requires: If an implementation has strict pointer safety ([basic.stc.dynamic.safety]) then ptr shall be a safely-derived pointer.

Default behavior: operator delete[](void* ptr, std::size_t size) calls operator delete[](ptr), and operator delete[](void* ptr) calls operator delete(ptr).

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

Effects: The deallocation function ([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.

Replaceable: a C++ program may define a function with signature void operator delete[](void* ptr, const std::nothrow_t&) noexcept that displaces the default version defined by the C++ standard library. If this function (without size parameter) is defined, the program should also define void operator delete[](void* ptr, std::size_t size, const std::nothrow_t&) noexcept. If this function with size parameter is defined, the program shall also define the 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: If an implementation has strict pointer safety ([basic.stc.dynamic.safety]) then ptr shall be a safely-derived pointer.

Requires: If present, the std::size_t size argument must equal the size argument passed to the allocation function that returned ptr.

Required behavior: Calls to operator delete[](void* ptr, std::size_t size, const std::nothrow_t&) may be changed to calls to operator delete[](void* ptr, const std::nothrow_t&) without affecting memory allocation. [ Note: A conforming implementation is for operator delete[](void* ptr, std::size_t size, const std::nothrow_t&) to simply call operator delete[](void* ptr, const std::nothrow_t&).  — end note ]

Default behavior: operator delete[](void* ptr, std::size_t size, const std::nothrow_t&) calls operator delete[](ptr, std::nothrow), and operator delete[](void* ptr, const std::nothrow_t&) calls operator delete[](ptr).

It is not the direct responsibility of operator new[](std::size_t) or operator delete[](void*) 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[](std::size_t) to obtain space to store supplemental information.

18.6.1.3 Placement forms [new.delete.placement]

These functions are reserved, a C++ program may not define functions that displace the versions in the Standard C++ 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 ([basic.stc.dynamic.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 ([basic.stc.dynamic.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]).

18.6.1.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 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 ([intro.multithread]) the next allocation (if any) in this order.

18.6.2 Storage allocation errors [alloc.errors]

18.6.2.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;
    virtual const char* what() const noexcept;
  };
}

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.

Remarks: The result of calling what() on the newly constructed object is implementation-defined.

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

Effects: Copies an object of class bad_alloc.

virtual const char* what() const noexcept;

Returns: An implementation-defined ntbs.

18.6.2.2 Class bad_array_new_length [new.badlength]

namespace std {
  class bad_array_new_length : public bad_alloc {
  public:
    bad_array_new_length() noexcept;
  };
}

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.

Remarks: the result of calling what() on the newly constructed object is implementation-defined.

18.6.2.3 Type new_handler [new.handler]

typedef void (*new_handler)();

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;

18.6.2.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.

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