16. Memory Allocation
- Rule 50
- Do not use
- Rule 51
- Always provide empty brackets
delete when deallocating arrays.
- Rec. 57
- Avoid global data if at all possible.
- Rec. 58
- Do not allocate memory and expect
that someone else will deallocate it later.
- Rec. 59
- Always assign a new value to a pointer
that points to deallocated memory.
In C++ data can be allocated statically, dynamically on the stack,
or dynamically on the heap. There are three categories of static data:
global data, global class data, and static data local to a function.
are used to allocate memory dynamically on the heap. This may lead to
conflicts with the use of the
operators in C++.
It is dangerous to:
delete for a pointer obtained via
malloc/realloc for objects having constructors,
free for anything allocated using
Thus, avoid whenever possible the use of
If an array
a having a type
T is allocated,
it is important to invoke
delete in the correct way. Only
delete a; will result in the destructor being
invoked only for the first object of type
T. By writing
delete [m] a; where
m is an integer which is
greater than the number of objects allocated earlier, the destructor
T will be invoked for memory that does not represent
objects of type
T. The easiest way to do this correctly
is to write
delete  a; since the destructor will then be
invoked only for those objects which have been allocated earlier.
Static data can cause several problems. In an environment where
parallel threads execute simultaneously, they can make the behaviour of
code unpredictable, since functions having static data are not reentrant.
One difference between ANSI-C and C++ is in how constants are
declared. If a variable is declared as a constant in ANSI-C, it has
the storage class
extern (global). In C++, however, it
normally has the storage class
static (local). The latter
means that a new instance of the constant object is created each time
a file includes the file which contains the declaration of the object,
unless the variable is explicitly declared extern in the include file.
An extern declaration in C++ does not mean that the variable
is initialized; there must be a definition for this in a definition
file. Static constants that are defined within a class are always external
and must always be defined separately.
It may, at times, be tempting to allocate memory for an object using
new, expecting someone else to deallocate the memory. For
instance, a function can allocate memory for an object which is then
returned to the user as the return value for the function. There is no
guarantee that the user will remember to deallocate the memory and the
interface with the function then becomes considerably more complex.
Pointers that point to deallocated memory should either be set to 0
or be given a new value to prevent access to the released memory. This
can be a very difficult problem to solve when there are several pointers
which point to the same memory, since C++ has no garbage collection.
Example 64: Right and wrong ways to invoke delete for arrays with destructors
- Exception to Rule 50
- No exceptions.
- Exception to Rule 51
- No exceptions.
int n = 7;
T* myT = new T[n]; // T is a type with defined constructors and destructors
delete myT; // No! Destructor only called for first object in array a
delete  myT; // No! Destructor called on memory out of bounds in array a
delete  myT; // OK, and always safe!
Example 65: Dangerous memory management
String myFunc( const char* myArgument )
String* temp = new String( myArgument );
// temp is never deallocated and the user of myFunc cannot deallocate
// because a temporary copy of that instance is returned.