The method for applying heap memory to a system in C + + is to use the new, new[] operator, new to request memory for a single object, new[] to request memory for an array of objects. The corresponding delete, delete[] operator returns the memory requested by the new, new[] operator back to the system. An expression using the new operator is called a new expression, and an expression that uses the delete operator is called a delete expression.
The C + + default new expression has 3 forms.
(1). The most basic is also the most common
New Type
New Type (initilalizers)
New Type[size]
New type[size]{braced initializer List}
(2). Specifies that no exception is thrown
New (Nothrow) type
New (Nothrow) type (initializers)
New (nothrow) type[size]
New (nothrow) type[size]{braced initializer list}
(3). Create only objects that do not allocate memory
New (place_address) type
New (place_address) type (initializers)
New (place_address) type[size]
New (place_address) type[size]{braced initializer list}
The default delete expression for C + + has only one form
Delete ptr
Delete[] ptr
Take the allocation of single-object memory as an example:
The new Expression 1 works as follows: 1. Call the void * operator new (size_t) function to allocate memory 2. Call the constructor of the object on the memory returned in 1th Step 3. Returns the memory pointer.
The new expression 1 is likely to throw an exception in steps 1th and 2nd. In the 1th step, if the system does not have enough memory to allocate, the void * operator new (size_t) function throws a Bad_alloc exception. In the 2nd step, if the object's constructor throws an exception, in order to prevent a memory leak, the compiler will catch the exception and then call the void operator delete (void *) function to reclaim the memory, and finally throw the exception again.
The new Expression 2 works as follows: 1. Call the void *operator new (size_t, const std::nothrow_t &) function to allocate memory 2. Call the constructor of the object on the memory returned in 1th Step 3. Returns the memory pointer.
The 1th step of the new expression 2 does not throw an exception without allocating memory, but instead returns a null pointer. In the 2nd step, if the object's constructor throws an exception, in order to prevent a memory leak, the compiler will also catch the exception and then reclaim the memory, but the function being called is void operator delete (void *,const std::nothrow_t &).
The new Expression 3 works as follows: 1. Call void *operator New (size_t,void *) to return memory 2. Call the constructor of the object on the memory returned in 1th Step 3. Returns the memory pointer.
The 1th step of the new expression 3 called void *operator new (size_t,void *) does not request memory from the system, but returns the second parameter. In this way, the construction of the 2nd Step object is performed on the user-specified memory. The 2nd step, like the above two, is to construct the object, but when the constructor throws an exception, the function that is called when the memory is reclaimed is void operator delete (void *,void *), which does nothing.
The new expression 2, 3 is also known as the position new expression.
The delete expression works as follows: 1. Call the destructor of the object 2. Call void operator delete (void *) to reclaim memory.
If it is an array version of the new expression, delete expression, the corresponding version of the above function is
void * operator new (size_t) corresponds to void * operator new[] (size_t)
void * operator new (size_t,const std::nothrow_t &) corresponds void * operator new[] (size_t,const std::nothrow_t &)
void * operator new (size_t,void *) corresponds to void * operator new[] (size_t,void *)
void operator delete (void *) corresponds to void operator delete[] (void *)
void operator delete (void *,const std::nothrow_t &) corresponds to void operator delete[] (void *,const std::nothrow_t &)
void operator delete (void *,void *) corresponds to void operator delete[] (void *,void *)
These 12 functions are located in the standard library <new>, except for the four functions of void *operator new (size_t,void *), the other 8 functions can be customized by the user.
There are two ways of customizing, the first being redefined in the global scope, and the second being redefined in the class scope. It is an error to define these 8 functions in namespace. In the case of a generic function, the first way is to cause a redefinition error, but the C + + standard Opens the backdoor for new and delete. The new and delete expressions look for the order in which they should actually use the function. If the object is a class type, the corresponding function is searched first in the class and in the member functions of the class's base class, if not, to the global scope. A user-defined version is used if there is a user-defined version in the global scope. If there is no user-defined version, the version of the standard library is used.
operator new series functions and operator new[] series functions are allocated n bytes of memory, then they are not different? The difference is there. operator new allocates a single object, n cannot be 0. In C + +, new type[0] is legal, and a non-null pointer must be returned (but the pointer cannot be dereferenced). So operator new[] series function to deal with the situation of n==0. Also, the delete[] expression is to be refactored on the object, but how does the delete[] expression know that there are several objects? So new[] when applying for memory to apply for additional memory to store the number of elements it requested, delete[] the time to read according to the rules of the line.
C + + new, delete