Back to Item 7: Never overload &&, ||, or ,
Continue to Exceptions

Item 8: Understand the different meanings of `new` and `delete`.

It occasionally seems as if people went out of their way to make C++ terminology difficult to understand. Case in point: the difference between the `new` operator and `operator` `new`.

When you write code like this,

    string *ps = new string("Memory Management");

the `new` you are using is the `new` operator. This operator is built into the language and, like `sizeof`, you can't change its meaning: it always does the same thing. What it does is twofold. First, it allocates enough memory to hold an object of the type requested. In the example above, it allocates enough memory to hold a `string` object. Second, it calls a constructor to initialize an object in the memory that was allocated. The `new` operator always does those two things; you can't change its behavior in any way.

What you can change is how the memory for an object is allocated. The `new` operator calls a function to perform the requisite memory allocation, and you can rewrite or overload that function to change its behavior. The name of the function the `new` operator calls to allocate memory is `operator` `new`. Honest.

The `operator` `new` function is usually declared like this:

    void * operator new(size_t size);

The return type is `void*`, because this function returns a pointer to raw, uninitialized memory. (If you like, you can write a version of `operator` `new` that initializes the memory to some value before returning a pointer to it, but this is not commonly done.) The `size_t` parameter specifies how much memory to allocate. You can overload `operator` `new` by adding additional parameters, but the first parameter must always be of type `size_t`. (For information on writing `operator` `new`, consult Items E8-E10.)

You'll probably never want to call `operator` `new` directly, but on the off chance you do, you'll call it just like any other function:

    void *rawMemory = operator new(sizeof(string));

Here `operator` `new` will return a pointer to a chunk of memory large enough to hold a `string` object.

Like `malloc`, `operator` `new`'s only responsibility is to allocate memory. It knows nothing about constructors. All `operator` `new` understands is memory allocation. It is the job of the `new` operator to take the raw memory that `operator` `new` returns and transform it into an object. When your compilers see a statement like

    string *ps = new string("Memory Management");

they must generate code that more or less corresponds to this (see Items E8 and E10, as well as the sidebar to my article on counting objects, for a more detailed treatment of this point):

    void *memory =                              // get raw memory
      operator new(sizeof(string));             // for a string
                                                // object

    call string::string("Memory Management")    // initialize the
    on *memory;                                 // object in the
                                                // memory

    string *ps =                                // make ps point to
      static_cast<string*>(memory);             // the new object

Notice that the second step above involves calling a constructor, something you, a mere programmer, are prohibited from doing. Your compilers are unconstrained by mortal limits, however, and they can do whatever they like. That's why you must use the `new` operator if you want to conjure up a heap-based object: you can't directly call the constructor necessary to initialize the object (including such crucial components as its vtbl — see Item 24).

Placement `new`

There are times when you really want to call a constructor directly. Invoking a constructor on an existing object makes no sense, because constructors initialize objects, and an object can only be initialized — given its first value — once. But occasionally you have some raw memory that's already been allocated, and you need to construct an object in the memory you have. A special version of `operator` `new` called placement `new` allows you to do it.

As an example of how placement `new` might be used, consider this:

    class Widget {
    public:
      Widget(int widgetSize);
      ...
    };

    Widget * constructWidgetInBuffer(void *buffer,
                                     int widgetSize)
    {
      return new (buffer) Widget(widgetSize);
    }

This function returns a pointer to a `Widget` object that's constructed within the buffer passed to the function. Such a function might be useful for applications using shared memory or memory-mapped I/O, because objects in such applications must be placed at specific addresses or in memory allocated by special routines. (For a different example of how placement `new` can be used, see Item 4.)

Inside `constructWidgetInBuffer`, the expression being returned is

    new (buffer) Widget(widgetSize)

This looks a little strange at first, but it's just a use of the `new` operator in which an additional argument (`buffer`) is being specified for the implicit call that the `new` operator makes to `operator` `new`. The `operator` `new` thus called must, in addition to the mandatory `size_t` argument, accept a `void*` parameter that points to the memory the object being constructed is to occupy. That `operator` `new` is placement `new`, and it looks like this:

    void * operator new(size_t, void *location)
    {
      return location;
    }

This is probably simpler than you expected, but this is all placement `new` needs to do. After all, the purpose of `operator` `new` is to find memory for an object and return a pointer to that memory. In the case of placement `new`, the caller already knows what the pointer to the memory should be, because the caller knows where the object is supposed to be placed. All placement `new` has to do, then, is return the pointer that's passed into it. (The unused (but mandatory) `size_t` parameter has no name to keep compilers from complaining about its not being used; see Item 6.) Placement `new` is part of the standard C++ library (see Item E49). To use placement `new`, all you have to do is `#include` `<new>` (or, if your compilers don't yet support the new-style header names (again, see Item E49), `<new.h>`).

If we step back from placement `new` for a moment, we'll see that the relationship between the `new` operator and `operator` `new`, though you want to create an object on the heap, use the `new` operator. It both allocates memory and calls a constructor for the object. If you only want to allocate memory, call `operator` `new`; no constructor will be called. If you want to customize the memory allocation that takes place when heap objects are created, write your own version of `operator` `new` and use the `new` operator; it will automatically invoke your custom version of `operator` `new`. If you want to construct an object in memory you've already got a pointer to, use placement `new`.

(For additional insights into variants of `new` and `delete`, see Item E7 and my article on counting objects.)

Deletion and Memory Deallocation

To avoid resource leaks, every dynamic allocation must be matched by an equal and opposite deallocation. The function `operator` `delete` is to the built-in `delete` operator as `operator` `new` is to the `new` operator. When you say something like this,

    string *ps;
    ...
    delete ps;                          // use the delete operator

your compilers must generate code both to destruct the object `ps` points to and to deallocate the memory occupied by that object.

The memory deallocation is performed by the `operator` `delete` function, which is usually declared like this:

    void operator delete(void *memoryToBeDeallocated);

Hence,

    delete ps;

causes compilers to generate code that approximately corresponds to this:

    ps->~string();                      // call the object's dtor

    operator delete(ps);                // deallocate the memory
                                        // the object occupied

One implication of this is that if you want to deal only with raw, uninitialized memory, you should bypass the `new` and `delete` operators entirely. Instead, you should call `operator` `new` to get the memory and `operator` `delete` to return it to the system:

    void *buffer =                      // allocate enough
      operator new(50*sizeof(char));    // memory to hold 50
                                        // chars; call no ctors

    ...

    operator delete(buffer);            // deallocate the memory;
                                        // call no dtors

This is the C++ equivalent of calling `malloc` and `free`.

If you use placement `new` to create an object in some memory, you should avoid using the `delete` operator on that memory. That's because the `delete` operator calls `operator` `delete` to deallocate the memory, but the memory containing the object wasn't allocated by `operator` `new` in the first place; placement `new` just returned the pointer that was passed to it. Who knows where that pointer came from? Instead, you should undo the effect of the constructor by explicitly calling the object's destructor:

    // functions for allocating and deallocating memory in
    // shared memory
    void * mallocShared(size_t size);
    void freeShared(void *memory);

    void *sharedMemory = mallocShared(sizeof(Widget));

    Widget *pw =                                   // as above,
      constructWidgetInBuffer(sharedMemory, 10);   // placement
                                                   // new is used

    ...

    delete pw;            // undefined! sharedMemory came from
                          // mallocShared, not operator new

    pw->~Widget();        // fine, destructs the Widget pointed to
                          // by pw, but doesn't deallocate the
                          // memory containing the Widget

    freeShared(pw);       // fine, deallocates the memory pointed
                          // to by pw, but calls no destructor

As this example demonstrates, if the raw memory passed to placement `new` was itself dynamically allocated (through some unconventional means), you must still deallocate that memory if you wish to avoid a memory leak. (See the sidebar to my article on counting objects for information on "placement `delete`".)

Arrays

So far so good, but there's farther to go. Everything we've examined so far concerns itself with only one object at a time. What about array allocation? What happens here?

    string *ps = new string[10];          // allocate an array of
                                          // objects

The `new` being used is still the `new` operator, but because an array is being created, the `new` operator behaves slightly differently from the case of single-object creation. For one thing, memory is no longer allocated by `operator` `new`. Instead, it's allocated by the array-allocation equivalent, a function called `operator` `new[]` (often referred to as "array `new`.") Like `operator` `new`, `operator` `new[]` can be overloaded. This allows you to seize control of memory allocation for arrays in the same way you can control memory allocation for single objects (but see Item E8 for some caveats on this).

(`operator` `new[]` is a relatively recent addition to C++, so your compilers may not support it yet. If they don't, the global version of `operator` `new` will be used to allocate memory for every array, regardless of the type of objects in the array. Customizing array-memory allocation under such compilers is daunting, because it requires that you rewrite the global `operator` `new`. This is not a task to be undertaken lightly. By default, the global `operator` `new` handles all dynamic memory allocation in a program, so any change in its behavior has a dramatic and pervasive effect. Furthermore, there is only one global `operator` `new` with the "normal" signature (i.e., taking the single `size_t` parameter — see Item E9), so if you decide to claim it as your own, you instantly render your software incompatible with any library that makes the same decision. (See also Item 27.) As a result of these considerations, custom memory management for arrays is not usually a reasonable design decision for compilers lacking support for `operator` `new[]`.)

The second way in which the `new` operator behaves differently for arrays than for objects is in the number of constructor calls it makes. For arrays, a constructor must be called for each object in the array:

    string *ps =               // call operator new[] to allocate
      new string[10];          // memory for 10 string objects,
                               // then call the default string
                               // ctor for each array element

Similarly, when the `delete` operator is used on an array, it calls a destructor for each array element and then calls `operator` `delete[]` to deallocate the memory:

    delete [] ps;              // call the string dtor for each
                               // array element, then call
                               // operator delete[] to
                               // deallocate the array's memory

Just as you can replace or overload `operator` `delete`, you can replace or overload `operator` `delete[]`. There are some restrictions on how they can be overloaded, however; consult a good C++ text for details. (For ideas on good C++ texts, see the recommendations beginning on page 285.)

So there you have it. The `new` and `delete` operators are built-in and beyond your control, but the memory allocation and deallocation functions they call are not. When you think about customizing the behavior of the `new` and `delete` operators, remember that you can't really do it. You can modify how they do what they do, but what they do is fixed by the language.

Back to Item 7: Never overload &&, ||, or ,
Continue to Exceptions