4.3 Memory Management Issues

Containers in the C++ Standard Library can maintain a variety of different types of elements. These include the fundamental datatypes (int, char, and so on), pointers, or user-defined types. Containers cannot hold references. In general, memory management is handled automatically by the standard container classes through the allocator template parameter type.

An allocator type can be provided as a second template parameter when declaring any container. Of course, if the allocator template parameter is provided explicitly, then its type must match the contained type. By default, all containers use the standard default allocator. See Section 15.3 for a discussion of user-defined allocators.

Values are placed into a container using the copy constructor. Some operations on a container require a default constructor. Generic algorithms that copy into a container, like std::copy(), use the assignment operator.

When an entire container is duplicated by invoking a copy constructor or by assignment, for example, every value is copied into the new structure using either the copy constructor or the assignment operator. Whether a deep copy or a shallow copy results is controlled by the programmer, who can provide the assignment operator with whatever meaning is desired. Memory for structures used internally by the various container classes is allocated and released automatically and efficiently.

If a destructor is defined for the element type, this destructor is invoked when values are removed from a container. When an entire collection is destroyed, the destructor is invoked for each remaining value being held by the container.

A few words should be said about containers that hold pointer values. Such collections are not uncommon. For example, a collection of pointers is the only way to store values that can potentially represent either instances of a class or instances of a subclass. Such a collection is encountered in an example problem discussed in Section 11.3.

In these cases, the container is responsible only for maintaining the pointer values themselves. It is the responsibility of the programmer to manage the memory for the values being referenced by the pointers. This includes making certain that the memory values are properly allocated, usually by invoking operator new; that they are not released while the container holds references to them; and that they are properly released once they have been removed from the container.