New and delete (C++)

From Wikipedia, the free encyclopedia
Jump to navigation Jump to search

Template:Short description Template:Lowercase In the C++ programming language, Template:Mono and Template:Mono are a pair of language constructs that perform dynamic memory allocation, object construction and object destruction.[1]

Overview

Except for a form called the "placement new", the Template:Mono operator denotes a request for memory allocation on a process's heap. If sufficient memory is available, Template:Mono initialises the memory, calling object constructors if necessary, and returns the address to the newly allocated and initialised memory.[2][3] A Template:Mono request, in its simplest form, looks as follows:

p = new T;

where Template:Mono is a previously declared pointer of type Template:Mono (or some other type to which a Template:Mono pointer can be assigned, such as a superclass of Template:Mono). The default constructor for Template:Mono, if any, is called to construct a Template:Mono instance in the allocated memory buffer.

If not enough memory is available in the free store for an object of type Template:Mono, the Template:Mono request indicates failure by throwing an exception of type Template:Mono. This removes the need to explicitly check the result of an allocation.

The deallocation counterpart of Template:Mono is Template:Mono, which first calls the destructor (if any) on its argument and then returns the memory allocated by Template:Mono back to the free store. Every call to Template:Mono must be matched by a call to Template:Mono; failure to do so causes a memory leak.[1]

Template:Mono syntax has several variants that allow finer control over memory allocation and object construction. A function call-like syntax is used to call a different constructor than the default one and pass it arguments, e.g.,

p = new T(argument);

calls a single-argument Template:Mono constructor instead of the default constructor when initializing the newly allocated buffer.

A different variant allocates and initialises arrays of objects rather than single objects:

p = new T [N];

This requests a memory buffer from the free store that is large enough to hold a contiguous array of Template:Mono objects of type Template:Mono, and calls the default constructor on each element of the array.

Memory allocated with the Template:Mono must be deallocated with the Template:Mono operator, rather than Template:Mono. Using the inappropriate form results in undefined behavior. C++ compilers are not required to generate a diagnostic message for using the wrong form.

The C++11 standard specifies an additional syntax,

p = new T[N] {initializer1, ..., initializerN};

that initializes each Template:Mono to Template:Mono.

Error handling

If Template:Mono cannot find sufficient memory to service an allocation request, it can report its error in three distinct ways. Firstly, the ISO C++ standard allows programs to register a custom function called a Template:Mono with the C++ runtime; if it does, then this function is called whenever Template:Mono encounters an error. The Template:Mono may attempt to make more memory available, or terminate the program if it can't.

If no Template:Mono is installed, Template:Mono instead throws an exception of type Template:Mono. Thus, the program does not need to check the value of the returned pointer, as is the habit in C; if no exception was thrown, the allocation succeeded.

The third method of error handling is provided by the variant form Template:Mono, which specifies that no exception should be thrown; instead, a null pointer is returned to signal an allocation error.

Overloading

The Template:Mono operator can be overloaded so that specific types (classes) use custom memory allocation algorithms for their instances. For example, the following is a variant of the singleton pattern where the first Template:Mono call allocates an instance and all subsequent calls return this same instance:

#include <cstdlib>
#include <cstddef>

class Singleton {
public:
  static void* operator new(std::size_t size) {
    if (!instance) {
      instance = std::malloc(size);
    }
    refcount++;
    return instance;
  }

  static void operator delete(void*) noexcept {
    if (--refcount == 0) {
      std::free(instance);
      instance = nullptr;
    }
  }

private:
  static void* instance = nullptr;
  static std::size_t refcount = 0;
};

This feature was available from early on in C++'s history, although the specific overloading mechanism changed. It was added to the language because object-oriented C++ programs tended to allocate many small objects with Template:Mono, which internally used the C allocator (see Template:Slink); that, however, was optimized for the fewer and larger allocations performed by typical C programs. Stroustrup reported that in early applications, the C function Template:Mono was "the most common performance bottleneck in real systems", with programs spending up to 50% of their time in this function.Template:R

Relation to malloc and free

Since standard C++ subsumes the C standard library, the C dynamic memory allocation routines Template:Mono, Template:Mono, Template:Mono and Template:Mono are also available to C++ programmers. The use of these routines is discouraged for most uses, since they do not perform object initialization and destruction.[4] Template:Mono and Template:Mono were, in fact, introduced in the first version of C++ (then called "C with Classes") to avoid the necessity of manual object initialization.[5]

In contrast to the C routines, which allow growing or shrinking an allocated array with Template:Mono, it is not possible to change the size of a memory buffer allocated by Template:Mono. The C++ standard library instead provides a dynamic array (collection) that can be extended or reduced in its Template:Mono template class.

The C++ standard does not specify any relation between Template:Mono/Template:Mono and the C memory allocation routines, but Template:Mono and Template:Mono are typically implemented as wrappers around Template:Mono and Template:Mono.[6] Mixing the two families of operations, e.g., Template:Mono'ing Template:Mono'ly allocated memory or Template:Mono'ing Template:Mono'd memory, causes undefined behavior and in practice can lead to various catastrophic results such as failure to release locks and thus deadlock.[7]

See also

References

Template:Reflist

Template:C++ programming language Template:Memory management navbox Script error: No such module "Navbox".

  1. a b Script error: No such module "citation/CS1".
  2. Script error: No such module "citation/CS1".
  3. Script error: No such module "citation/CS1".
  4. Script error: No such module "citation/CS1".
  5. Script error: No such module "citation/CS1".
  6. Script error: No such module "citation/CS1".
  7. Script error: No such module "citation/CS1". Section 4.4, Common C++ Memory Management Errors.