[basic.stc.dynamic]

# 6 Basics [[basic]](./#basic)

## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc.dynamic)

### 6.8.6 Storage duration [[basic.stc]](basic.stc#dynamic)

#### 6.8.6.5 Dynamic storage duration [basic.stc.dynamic]

#### [6.8.6.5.1](#general) General [[basic.stc.dynamic.general]](basic.stc.dynamic.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4362)

Objects can be created dynamically during [program
execution](intro.execution "6.10.1 Sequential execution [intro.execution]"), using[*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]")*s* ([[expr.new]](expr.new "7.6.2.8 New")), and destroyed using[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9 Delete [expr.delete]")*s* ([[expr.delete]](expr.delete "7.6.2.9 Delete"))[.](#general-1.sentence-1)

A C++ implementation
provides access to, and management of, dynamic storage via
the global [*allocation functions*](#def:allocation_function "6.8.6.5.1 General [basic.stc.dynamic.general]")operator new andoperator new[] and
the global [*deallocation functions*](#def:deallocation_function "6.8.6.5.1 General [basic.stc.dynamic.general]")operator delete andoperator delete[][.](#general-1.sentence-2)

[*Note [1](#general-note-1)*:

The non-allocating forms described in [[new.delete.placement]](new.delete.placement "17.6.3.4 Non-allocating forms") do not perform allocation or deallocation[.](#general-1.sentence-3)

â *end note*]

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4381)

The library provides default definitions for the global allocation and
deallocation functions[.](#general-2.sentence-1)

Some global allocation and deallocation
functions are replaceable ([[dcl.fct.def.replace]](dcl.fct.def.replace#term.replaceable.function "9.6.5 Replaceable function definitions"))[.](#general-2.sentence-2)

The following allocation and deallocation functions ([[support.dynamic]](support.dynamic "17.6 Dynamic memory management"))
are implicitly declared in global scope in each translation unit of a
program[.](#general-2.sentence-3)

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

void operator delete(void*) noexcept;void operator delete(void*, std::size_t) noexcept;void operator delete(void*, std::align_val_t) noexcept;void operator delete(void*, std::size_t, std::align_val_t) noexcept;

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

void operator delete[](void*) noexcept;void operator delete[](void*, std::size_t) noexcept;void operator delete[](void*, std::align_val_t) noexcept;void operator delete[](void*, std::size_t, std::align_val_t) noexcept;

These implicit declarations introduce only the function namesoperator new,operator new[],operator delete, andoperator delete[][.](#general-2.sentence-4)

[*Note [2](#general-note-2)*:

The implicit declarations do not introduce
the names std,std​::​size_t,std​::​align_val_t,
or any other names that the library uses to
declare these names[.](#general-2.sentence-5)

Thus, a [*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]"),[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9 Delete [expr.delete]"), or function call that refers to one of
these functions without importing or including the header [<new>](support.dynamic.general#header:%3cnew%3e "17.6.1 General [support.dynamic.general]") or importing a C++ library module ([[std.modules]](std.modules "16.4.2.4 Modules"))
is well-formed[.](#general-2.sentence-6)

However, referring to std or std​::​size_t or std​::​align_val_t is ill-formed unless
a standard library declaration ([[cstddef.syn]](cstddef.syn "17.2.1 Header <cstddef> synopsis"), [[new.syn]](new.syn "17.6.2 Header <new> synopsis"), [[std.modules]](std.modules "16.4.2.4 Modules"))
of that name precedes ([[basic.lookup.general]](basic.lookup.general "6.5.1 General")) the use of that name[.](#general-2.sentence-7)

â *end note*]

Allocation and/or
deallocation functions may also be declared and defined for any
class ([[class.free]](class.free "11.4.11 Allocation and deallocation functions"))[.](#general-2.sentence-8)

[3](#general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4433)

If the behavior of an allocation or deallocation function
does not satisfy the semantic constraints
specified in [[basic.stc.dynamic.allocation]](#allocation "6.8.6.5.2 Allocation functions") and [[basic.stc.dynamic.deallocation]](#deallocation "6.8.6.5.3 Deallocation functions"),
the behavior is undefined[.](#general-3.sentence-1)

#### [6.8.6.5.2](#allocation) Allocation functions [[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation)

[1](#allocation-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4444)

An allocation function that is not a class member function
shall belong to the global scope and not have a name with internal linkage[.](#allocation-1.sentence-1)

The return type shall be void*[.](#allocation-1.sentence-2)

The first
parameter shall have type std​::​size_t ([[support.types]](support.types "17.2 Common definitions"))[.](#allocation-1.sentence-3)

The
first parameter shall not have an associated default
argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments"))[.](#allocation-1.sentence-4)

The value of the first parameter
is interpreted as the requested size of the allocation[.](#allocation-1.sentence-5)

An allocation
function can be a function template[.](#allocation-1.sentence-6)

Such a template shall declare its
return type and first parameter as specified above (that is, template
parameter types shall not be used in the return type and first parameter
type)[.](#allocation-1.sentence-7)

Allocation function templates shall have two or more parameters[.](#allocation-1.sentence-8)

[2](#allocation-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4458)

An allocation function attempts to allocate the requested amount of
storage[.](#allocation-2.sentence-1)

If it is successful, it returns the address of the start
of a block of storage whose length in bytes is at least as large
as the requested size[.](#allocation-2.sentence-2)

The order,
contiguity, and initial value of storage allocated by successive calls
to an allocation function are unspecified[.](#allocation-2.sentence-3)

Even if the size of the space
requested is zero, the request can fail[.](#allocation-2.sentence-4)

If the request succeeds, the
value returned by a replaceable allocation function
is a non-null pointer value ([[basic.compound]](basic.compound "6.9.4 Compound types"))p0 different from any previously returned value p1,
unless that value p1 was subsequently passed to a
replaceable deallocation function[.](#allocation-2.sentence-5)

Furthermore, for the library allocation functions
in [[new.delete.single]](new.delete.single "17.6.3.2 Single-object forms") and [[new.delete.array]](new.delete.array "17.6.3.3 Array forms"),p0 represents the address of a block of storage disjoint from the storage
for any other object accessible to the caller[.](#allocation-2.sentence-6)

The effect of indirecting through a pointer
returned from a request for zero size is undefined[.](#allocation-2.sentence-7)[23](#footnote-23 "The intent is to have operator new() implementable by calling std​::​malloc() or std​::​calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non-null pointer.")

[3](#allocation-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4487)

For an allocation function other than
a reserved placement allocation function ([[new.delete.placement]](new.delete.placement "17.6.3.4 Non-allocating forms")),
the pointer returned on a successful call
shall represent the address of storage that is aligned as follows:

- [(3.1)](#allocation-3.1)

  If the allocation function takes an argument
 of type std​::​align_val_t,
 the storage will have the alignment specified
 by the value of this argument[.](#allocation-3.1.sentence-1)

- [(3.2)](#allocation-3.2)

  Otherwise, if the allocation function is named operator new[],
 the storage is aligned for any object that
 does not have new-extended alignment ([[basic.align]](basic.align "6.8.3 Alignment")) and
 is no larger than the requested size[.](#allocation-3.2.sentence-1)

- [(3.3)](#allocation-3.3)

  Otherwise, the storage is aligned for any object that
 does not have new-extended alignment and is of the requested size[.](#allocation-3.3.sentence-1)

[4](#allocation-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4508)

An allocation function that fails to allocate storage can invoke the
currently installed new-handler function ([[new.handler]](new.handler "17.6.4.3 Type new_­handler")), if any[.](#allocation-4.sentence-1)

[*Note [1](#allocation-note-1)*:

A program-supplied allocation function can obtain the
currently installed new_handler using thestd​::​get_new_handler function ([[get.new.handler]](get.new.handler "17.6.4.5 get_­new_­handler"))[.](#allocation-4.sentence-2)

â *end note*]

An allocation function that has a non-throwing
exception specification ([[except.spec]](except.spec "14.5 Exception specifications"))
indicates failure by returning
a null pointer value[.](#allocation-4.sentence-3)

Any other allocation function
never returns a null pointer value and
indicates failure only by throwing an exception ([[except.throw]](except.throw "14.2 Throwing an exception")) of a type
that would match a handler ([[except.handle]](except.handle "14.4 Handling an exception")) of typestd​::​bad_alloc ([[bad.alloc]](bad.alloc "17.6.4.1 Class bad_­alloc"))[.](#allocation-4.sentence-4)

[5](#allocation-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4527)

A global allocation function is only called as the result of a [new
expression](expr.new "7.6.2.8 New [expr.new]"), or called directly using the [function call](expr.call "7.6.1.3 Function call [expr.call]") syntax, or called indirectly to allocate storage for
a coroutine state ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4 Coroutine definitions")),
or called indirectly through calls to the
functions in the C++ standard library[.](#allocation-5.sentence-1)

[*Note [2](#allocation-note-2)*:

In particular, a
global allocation function is not called to allocate storage
for objects with static storage duration ([[basic.stc.static]](basic.stc.static "6.8.6.2 Static storage duration")),
for objects or references with thread storage duration ([[basic.stc.thread]](basic.stc.thread "6.8.6.3 Thread storage duration")),
for objects of type std​::​type_info ([[expr.typeid]](expr.typeid "7.6.1.8 Type identification")),
for an object of type std​::​contracts​::​contract_violation when a contract violation occurs ([[basic.contract.eval]](basic.contract.eval "6.11.2 Evaluation")), or
for an exception object ([[except.throw]](except.throw "14.2 Throwing an exception"))[.](#allocation-5.sentence-2)

â *end note*]

[23)](#footnote-23)[23)](#footnoteref-23)

The intent is
to have operator new() implementable by
calling std​::​malloc() or std​::​calloc(), so the rules are
substantially the same[.](#footnote-23.sentence-1)

C++ differs from C in requiring a zero request
to return a non-null pointer[.](#footnote-23.sentence-2)

#### [6.8.6.5.3](#deallocation) Deallocation functions [[basic.stc.dynamic.deallocation]](basic.stc.dynamic.deallocation)

[1](#deallocation-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4547)

A deallocation function that is not a class member function
shall belong to the global scope and not have a name with internal linkage[.](#deallocation-1.sentence-1)

[2](#deallocation-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4552)

A deallocation function
is a [*destroying operator delete*](#def:operator_delete,destroying "6.8.6.5.3 Deallocation functions [basic.stc.dynamic.deallocation]") if it has at least two parameters
and its second parameter
is of type std​::​destroying_delete_t[.](#deallocation-2.sentence-1)

A destroying operator delete
shall be a class member function named operator delete[.](#deallocation-2.sentence-2)

[*Note [1](#deallocation-note-1)*:

Array deletion cannot use a destroying operator delete[.](#deallocation-2.sentence-3)

â *end note*]

[3](#deallocation-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4564)

Each deallocation function shall return void[.](#deallocation-3.sentence-1)

If the function is a destroying operator delete
declared in class type C,
the type of its first parameter shall be C*;
otherwise, the type of its first
parameter shall be void*[.](#deallocation-3.sentence-2)

A deallocation function may have more
than one parameter[.](#deallocation-3.sentence-3)

A [*usual deallocation function*](#def:usual_deallocation_function "6.8.6.5.3 Deallocation functions [basic.stc.dynamic.deallocation]") is a deallocation function
whose parameters after the first are

- [(3.1)](#deallocation-3.1)

optionally, a parameter of type std​::​destroying_delete_t, then

- [(3.2)](#deallocation-3.2)

optionally, a parameter of type std​::​size_t,[24](#footnote-24 "The global operator delete(void*, std​::​size_­t) precludes use of an allocation function void operator new(std​::​size_­t, std​::​size_­t) as a placement allocation function ([diff.cpp11.basic]).") then

- [(3.3)](#deallocation-3.3)

optionally, a parameter of type std​::​align_val_t[.](#deallocation-3.sentence-4)

A destroying operator delete shall be a usual deallocation function[.](#deallocation-3.sentence-5)

A deallocation function may be an instance of a function
template[.](#deallocation-3.sentence-6)

Neither the first parameter nor the return type shall depend
on a template parameter[.](#deallocation-3.sentence-7)

A deallocation
function template shall have two or more function parameters[.](#deallocation-3.sentence-8)

A template
instance is never a usual deallocation function, regardless of its
signature[.](#deallocation-3.sentence-9)

[4](#deallocation-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4600)

If a deallocation function terminates by throwing an exception, the behavior is undefined[.](#deallocation-4.sentence-1)

The value of the first argument supplied to a deallocation function may
be a null pointer value; if so, and if the deallocation function is one
supplied in the standard library, the call has no effect[.](#deallocation-4.sentence-2)

[5](#deallocation-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4606)

If the argument given to a deallocation function in the standard library
is a pointer that is not the null pointer value ([[basic.compound]](basic.compound "6.9.4 Compound types")), the
deallocation function shall deallocate the storage referenced by the
pointer, ending the duration of the region of storage[.](#deallocation-5.sentence-1)

[24)](#footnote-24)[24)](#footnoteref-24)

The global operator delete(void*, std​::​size_t) precludes use of an
allocation function void operator new(std​::​size_t, std​::​size_t) as a placement
allocation function ([[diff.cpp11.basic]](diff.cpp11.basic "C.5.3 [basic]: basics"))[.](#footnote-24.sentence-1)
