[util.smartptr.shared.create]

# 20 Memory management library [[mem]](./#mem)

## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.create)

### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.create)

#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#create)

#### 20.3.2.2.7 Creation [util.smartptr.shared.create]

[1](#1)

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

The common requirements that apply to allmake_shared,allocate_shared,make_shared_for_overwrite, andallocate_shared_for_overwrite overloads,
unless specified otherwise, are described below[.](#1.sentence-1)

[ð](#lib:make_shared)

`template<class T, ...>
  constexpr shared_ptr<T> make_shared(args);
template<class T, class A, ...>
  constexpr shared_ptr<T> allocate_shared(const A& a, args);
template<class T, ...>
  constexpr shared_ptr<T> make_shared_for_overwrite(args);
template<class T, class A, ...>
  constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
`

[2](#2)

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

*Preconditions*: A meets
the [*Cpp17Allocator*](allocator.requirements.general#:Cpp17Allocator "16.4.4.6.1 General [allocator.requirements.general]") requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))[.](#2.sentence-1)

[3](#3)

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

*Effects*: Allocates memory for an object of type T (or U[N] when T is U[],
where N is determined from *args* as specified by the concrete overload)[.](#3.sentence-1)

The object is initialized from *args* as specified by the concrete overload[.](#3.sentence-2)

The allocate_shared and allocate_shared_for_overwrite templates
use a copy of a (rebound for an unspecified value_type) to allocate memory[.](#3.sentence-3)

If an exception is thrown, the functions have no effect[.](#3.sentence-4)

[4](#4)

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

*Postconditions*: r.get() != nullptr && r.use_count() == 1,
where r is the return value[.](#4.sentence-1)

[5](#5)

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

*Returns*: A shared_ptr instance that stores and owns the address of
the newly constructed object[.](#5.sentence-1)

[6](#6)

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

*Throws*: bad_alloc, or
an exception thrown from allocate or from the initialization of the object[.](#6.sentence-1)

[7](#7)

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

*Remarks*: 

- [(7.1)](#7.1)

  Implementations should perform no more than one memory allocation[.](#7.1.sentence-1)
  [*Note [1](#note-1)*:
  This provides efficiency equivalent to an intrusive smart pointer[.](#7.1.sentence-2)
 â *end note*]

- [(7.2)](#7.2)

  When an object of an array type U is specified to have
 an initial value of u (of the same type),
 this shall be interpreted to mean that
 each array element of the object has as its initial value
 the corresponding element from u[.](#7.2.sentence-1)

- [(7.3)](#7.3)

  When an object of an array type is specified to have
 a default initial value,
 this shall be interpreted to mean that each array element of the object
 has a default initial value[.](#7.3.sentence-1)

- [(7.4)](#7.4)

  When a (sub)object of a non-array type U is specified to have
 an initial value of v, or U(l...),
 where l... is a list of constructor arguments, make_shared shall initialize this (sub)object
 via the expression ​::​new(pv) U(v) or ​::​new(pv) U(l...) respectively,
 where pv has type void* and points to storage
 suitable to hold an object of type U[.](#7.4.sentence-1)

- [(7.5)](#7.5)

  When a (sub)object of a non-array type U is specified to have
 an initial value of v, or U(l...),
 where l... is a list of constructor arguments, allocate_shared shall initialize this (sub)object
 via the expression
  * [(7.5.1)](#7.5.1)

allocator_traits<A2>​::​construct(a2, pu, v) or

  * [(7.5.2)](#7.5.2)

allocator_traits<A2>​::​construct(a2, pu, l...)

respectively,
 where pu is a pointer of type remove_cv_t<U>* pointing to storage
 suitable to hold an object of type remove_cv_t<U> and a2 of type A2 is a potentially rebound copy of
 the allocator a passed to allocate_shared[.](#7.5.sentence-1)

- [(7.6)](#7.6)

  When a (sub)object of non-array type U is specified to have
 a default initial value, make_shared shall initialize this (sub)object
 via the expression ​::​new(pv) U(),
 where pv has type void* and points to storage
 suitable to hold an object of type U[.](#7.6.sentence-1)

- [(7.7)](#7.7)

  When a (sub)object of non-array type U is specified to have
 a default initial value, allocate_shared initializes this (sub)object
 via the expression allocator_traits<A2>​::​construct(a2, pu),
 where pu is a pointer of type remove_cv_t<U>* pointing to storage
 suitable to hold an object of type remove_cv_t<U> and a2 of type A2 is a potentially rebound copy of
 the allocator a passed to allocate_shared[.](#7.7.sentence-1)

- [(7.8)](#7.8)

  When a (sub)object of non-array type U is initialized by make_shared_for_overwrite or allocate_shared_for_overwrite,
 it is initialized via the expression ​::​new(pv) U,
 where pv has type void* and
 points to storage suitable to hold an object of type U[.](#7.8.sentence-1)

- [(7.9)](#7.9)

  Array elements are initialized in ascending order of their addresses[.](#7.9.sentence-1)

- [(7.10)](#7.10)

  When the lifetime of the object managed by the return value ends, or
 when the initialization of an array element throws an exception,
 the initialized elements are destroyed in the reverse order
 of their original construction[.](#7.10.sentence-1)

- [(7.11)](#7.11)

  When a (sub)object of non-array type U that was initialized by make_shared, make_shared_for_overwrite, or allocate_shared_for_overwrite is to be destroyed,
 it is destroyed via the expression pu->~U() where pu points to that object of type U[.](#7.11.sentence-1)

- [(7.12)](#7.12)

  When a (sub)object of non-array type U that was initialized by allocate_shared is to be destroyed,
 it is destroyed via the expression allocator_traits<A2>​::​destroy(a2, pu) where pu is a pointer of type remove_cv_t<U>* pointing to that object of type remove_cv_t<U> and a2 of type A2 is a potentially rebound copy of
 the allocator a passed to allocate_shared[.](#7.12.sentence-1)

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

These functions will typically allocate more memory than sizeof(T) to
allow for internal bookkeeping structures such as reference counts[.](#7.sentence-2)

â *end note*]

[ð](#lib:make_shared_)

`template<class T, class... Args>
  constexpr shared_ptr<T> make_shared(Args&&... args);                    // T is not array
template<class T, class A, class... Args>
  constexpr shared_ptr<T> allocate_shared(const A& a, Args&&... args);    // T is not array
`

[8](#8)

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

*Constraints*: T is not an array type[.](#8.sentence-1)

[9](#9)

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

*Returns*: A shared_ptr to an object of type T with an initial value T(std​::​forward<Args>(args)...)[.](#9.sentence-1)

[10](#10)

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

*Remarks*: The shared_ptr constructors called by these functions
enable shared_from_this with the address of the newly constructed object of type T[.](#10.sentence-1)

[11](#11)

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

[*Example [1](#example-1)*: shared_ptr<int> p = make_shared<int>(); // shared_ptr to int() shared_ptr<vector<int>> q = make_shared<vector<int>>(16, 1); // shared_ptr to vector of 16 elements with value 1 â *end example*]

[ð](#lib:make_shared__)

`template<class T>
  constexpr shared_ptr<T> make_shared(size_t N);                          // T is U[]
template<class T, class A>
  constexpr shared_ptr<T> allocate_shared(const A& a, size_t N);          // T is U[]
`

[12](#12)

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

*Constraints*: T is of the form U[][.](#12.sentence-1)

[13](#13)

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

*Returns*: A shared_ptr to an object of type U[N] with a default initial value,
where U is remove_extent_t<T>[.](#13.sentence-1)

[14](#14)

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

[*Example [2](#example-2)*: shared_ptr<double[]> p = make_shared<double[]>(1024); // shared_ptr to a value-initialized double[1024] shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6); // shared_ptr to a value-initialized double[6][2][2] â *end example*]

[ð](#lib:make_shared___)

`template<class T>
  constexpr shared_ptr<T> make_shared();                                  // T is U[N]
template<class T, class A>
  constexpr shared_ptr<T> allocate_shared(const A& a);                    // T is U[N]
`

[15](#15)

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

*Constraints*: T is of the form U[N][.](#15.sentence-1)

[16](#16)

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

*Returns*: A shared_ptr to an object of type T with a default initial value[.](#16.sentence-1)

[17](#17)

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

[*Example [3](#example-3)*: shared_ptr<double[1024]> p = make_shared<double[1024]>(); // shared_ptr to a value-initialized double[1024] shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>(); // shared_ptr to a value-initialized double[6][2][2] â *end example*]

[ð](#lib:make_shared____)

`template<class T>
  constexpr shared_ptr<T> make_shared(size_t N,
                                      const remove_extent_t<T>& u);     // T is U[]
template<class T, class A>
  constexpr shared_ptr<T> allocate_shared(const A& a, size_t N,
                                          const remove_extent_t<T>& u); // T is U[]
`

[18](#18)

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

*Constraints*: T is of the form U[][.](#18.sentence-1)

[19](#19)

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

*Returns*: A shared_ptr to an object of type U[N],
where U is remove_extent_t<T> and
each array element has an initial value of u[.](#19.sentence-1)

[20](#20)

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

[*Example [4](#example-4)*: shared_ptr<double[]> p = make_shared<double[]>(1024, 1.0); // shared_ptr to a double[1024], where each element is 1.0 shared_ptr<double[][2]> q = make_shared<double[][2]>(6, {1.0, 0.0}); // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0} shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2}); // shared_ptr to a vector<int>[4], where each vector has contents {1, 2} â *end example*]

[ð](#lib:make_shared_____)

`template<class T>
  constexpr shared_ptr<T> make_shared(const remove_extent_t<T>& u);       // T is U[N]
template<class T, class A>
  constexpr shared_ptr<T> allocate_shared(const A& a,
                                          const remove_extent_t<T>& u);   // T is U[N]
`

[21](#21)

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

*Constraints*: T is of the form U[N][.](#21.sentence-1)

[22](#22)

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

*Returns*: A shared_ptr to an object of type T,
where each array element of type remove_extent_t<T> has an initial value of u[.](#22.sentence-1)

[23](#23)

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

[*Example [5](#example-5)*: shared_ptr<double[1024]> p = make_shared<double[1024]>(1.0); // shared_ptr to a double[1024], where each element is 1.0 shared_ptr<double[6][2]> q = make_shared<double[6][2]>({1.0, 0.0}); // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0} shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2}); // shared_ptr to a vector<int>[4], where each vector has contents {1, 2} â *end example*]

[ð](#lib:make_shared______)

`template<class T>
  constexpr shared_ptr<T> make_shared_for_overwrite();
template<class T, class A>
  constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a);
`

[24](#24)

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

*Constraints*: T is not an array of unknown bound[.](#24.sentence-1)

[25](#25)

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

*Returns*: A shared_ptr to an object of type T[.](#25.sentence-1)

[26](#26)

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

[*Example [6](#example-6)*: struct X { double data[1024]; };
shared_ptr<X> p = make_shared_for_overwrite<X>(); // shared_ptr to a default-initialized X, where each element in X​::​data has an indeterminate value shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>(); // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value â *end example*]

[ð](#lib:make_shared_______)

`template<class T>
  constexpr shared_ptr<T> make_shared_for_overwrite(size_t N);
template<class T, class A>
  constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
`

[27](#27)

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

*Constraints*: T is an array of unknown bound[.](#27.sentence-1)

[28](#28)

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

*Returns*: A shared_ptr to an object of type U[N],
where U is remove_extent_t<T>[.](#28.sentence-1)

[29](#29)

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

[*Example [7](#example-7)*: shared_ptr<double[]> p = make_shared_for_overwrite<double[]>(1024); // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value â *end example*]
