new
From Cppwiki
The new keyword is used to construct one or more objects of a particular type. It has two forms:
- new - Construct a single object
- new[] - Construct one or more objects, specified through a count value between the brackets
Unless the placement new syntax is used, the new keyword also preallocates space for the objects it constructs. This is done using the operator new functions, which allocate raw, uninitialized memory from the free store.
Contents |
Usage
Both forms of new return a pointer to an allocated block of memory. In the case of operator new, a pointer to a single object is returned; the pointer from new[], obviously, points to an array. The usage is:
T* my_t_ptr = new T; T* my_t_array = new T[size];
Using new
Generally it is preferred to avoid direct memory management, in favor of RAII. In the case where you absolutely have to manage allocation and deallocation yourself, care needs to be taken to use new properly. Careless use of new can lead to memory leaks and heap corruption. The differences between the two forms of new are outlined below.
new
With the single operator new you only create one object at a time. The benefit to this is that you can specify class constructors when using this type of new. If, for instance, you were creating a new string, and you wanted to initialize it with the value "This is my string", it would look like:
std::string* my_string = new std::string("This is my string");If only the type is given, with no arguments for a constructor, the default constructor is called.
Alternatives to solutions involving new
RAII (including standard containers) should generally be used in the place of direct memory management. In the case of a single object being handled by a pointer, a smart pointer can be used instead.
new[]
In contrast, with array new you cannot specify any arguments to constructors. When allocating arrays with new, the default constructor is called for every object. This is problematic if you have a class that has no default constructor, and you're unable to provide one.
std::string* my_strings = new std::string[size];
Alternatives to solutions involving new[]
As previously mentioned, RAII is usually favored above the use of new. A common container class that is preferred above new[] is std::vector which handles allocation and deallocation automatically, and with some usage allows you to specify how elements are created.
Deallocation
It's important to use the correct form of delete when you're ready to free memory allocated with new. Unlike objects placed on the stack the memory isn't released for you automatically, and no destructors are ever called unless you delete the pointers you've allocated. Failure to use the correct form of delete results in undefined behavior.
Keyword new vs. operator new
The execution of a new expression is easiest explained as a two phase process. When new, or new[], is invoked, the first action taken is the allocation of the memory required; this falls under the auspices of operator new. Because new is an operator, it can be overloaded -- unlike most operators, however, new can also be overloaded at the global scope.
An example of how a (global) new overload might look:
#include <new>
#include <cstdlib>
void* operator new(std::size_t size) throw (std::bad_alloc)
{
if (!size)
{
size = 1;
}
void* p = 0;
while (!(p = std::malloc(size)))
{
new_handler nh = std::set_new_handler(0); // There is no other way to get the new_handler
std::set_new_handler(nh);
if (!nh)
{
throw std::bad_alloc();
}
nh();
}
return p;
}When overloading operator new, because the underlying allocation method has changed, it's imperitive that you also write a corresponding operator delete. Also note that operator new is different from operator new[], though the code for each overload (not provided) may appear similar. By extension, operator delete is unique from operator delete[]. This applies at both the global, and class levels.
Keyword new
One thing conspicuously absent from the above example is the invokation of a constructor. The 'keyword new' functionality is unique from the operator new functionality. Where operator new, or operator new[], are responsible for allocation of memory, keyword new is responsible for invoking constructors for all objects created. This applies to single objects, as well as arrays, and the behavior of the new keyword can not be changed.
Placement new
Placement new is a special form of new. It is the converse of operator new; it does not allocate any memory, but instead invokes constructors on already allocated memory. For instance,
T *t = new T(42);
Could instead be written:
T *t = ::operator new(sizeof(T)); new (t) T (42);
The (t) syntax provides the location of the already allocated memory where the object should be constructed.
The reverse of placement new is an explicit destructor invokation:
t->~T(); ::operator delete(t);
Placement new actually works by invoking a special variant of operator new:
void *operator new(std::size_t, void *p) throw() {
return p;
}
nothrow
Another special variant of operator new is
void *operator new(std::size_t, const std::nothrow_t &) throw();
This is invoked using the global object std::nothrow:
T *t = new (std::nothrow) T(42);
The nothrow version of operator new will return NULL on allocation failure, instead of throwing std::bad_alloc.

