327 lines
16 KiB
Markdown
327 lines
16 KiB
Markdown
[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)
|