Namespaces
Variants
Actions

new expression

From cppreference.com
< cpp‎ | language
 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
new expression
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Creates and initializes objects with dynamic storage duration, that is, objects whose lifetime is not necessarily limited by the scope in which they were created.

Contents

[edit] Syntax

::(optional) new (type ) new-initializer (optional) (1)
::(optional) new type new-initializer (optional) (2)
::(optional) new (placement-args ) (type ) new-initializer (optional) (3)
::(optional) new (placement-args ) type new-initializer (optional) (4)
1,2) Attempts to create an object of type, denoted by the type-id type, which may be array type, and may include a placeholder type specifier(since C++11), or include a class template name whose argument is to be deduced by class template argument deduction(since C++17).
3,4) Same as (1,2), but provides additional arguments to the allocation function, see placement new.

[edit] Explanation

type - the target type-id
new-initializer - a parentheses-enclosed expression list or a brace-enclosed initializer list(since C++11)
placement-args - additional placement arguments


The new expression attempts to allocate storage and then attempts to construct and initialize either a single unnamed object, or an unnamed array of objects in the allocated storage. The new expression returns a prvalue pointer to the constructed object or, if an array of objects was constructed, a pointer to the initial element of the array.

Syntax (1) or (3) is required if type includes parentheses:

new int(*[10])();    // error: parsed as (new int) (*[10]) ()
new (int (*[10])()); // okay: allocates an array of 10 pointers to functions

In addition, type is parsed greedily: it will be taken include every token that can be a part of a declarator:

new int + 1; // okay: parsed as (new int) + 1, increments a pointer returned by new int
new int * 1; // error: parsed as (new int*) (1)

The new-initializer is not optional if

  • a placeholder is used in type, that is, auto or decltype(auto)(since C++14), possibly combined with a type constraint(since C++20),
(since C++11)
  • a class template is used in type whose arguments need to be deduced.
(since C++17)
double* p = new double[]{1, 2, 3}; // creates an array of type double[3]
auto p = new auto('c');            // creates a single object of type char. p is a char*
 
auto q = new std::integral auto(1);         // OK: q is an int*
auto q = new std::floating_point auto(true) // ERROR: type constraint not satisfied
 
auto r = new std::pair(1, true); // OK: r is a std::pair<int, bool>*
auto r = new std::vector;        // ERROR: element type can't be deduced

[edit] Dynamic arrays

If type is an array type, all dimensions other than the first must be specified as positive integral constant expression(until C++14)converted constant expression of type std::size_t(since C++14), but (only when using un-parenthesized syntaxes (2) and (4)) the first dimension may be an expression of integral type, enumeration type, or class type with a single non-explicit conversion function to integral or enumeration type(until C++14)any expression convertible to std::size_t(since C++14). This is the only way to directly create an array with size defined at runtime, such arrays are often referred to as dynamic arrays:

int n = 42;
double a[n][5]; // error
auto p1 = new  double[n][5];  // OK
auto p2 = new  double[5][n];  // error: only the first dimension may be non-constant
auto p3 = new (double[n][5]); // error: syntax (1) cannot be used for dynamic arrays

The behavior is undefined if the value in the first dimension (converted to integral or enumeration type if needed) is negative.

(until C++11)

In the following cases the value of the expression specifying the first dimension is invalid:

  • the expression is of non-class type and its value before conversion to std::size_t is negative;
  • the expression is of class type and its value after user-defined conversion function and before the second standard conversion is negative;
  • the value of the expression is larger than some implementation-defined limit;
  • the value is smaller than the number of array elements provided in the brace-enclosed initializer list (including the terminating '\0' on a string literal).

If the value in the first dimension is invalid for any of these reasons,