Programs that use the
new operator to create arrays or
structs at run-time are said to use
dynamic memory.
When dynamic memory is no longer needed, it should be returned
to the system for reuse.
Q: Why?
-
A: A program that runs a long time, repetitively
allocating memory without giving it back, could eventually
run out of memory.
This is metaphorically referred to as a memory leak.
To free all the memory taken by linked structures, you must
"chase down" pointers struct by struct, explicitly freeing
the memory for each one.
Care must be taken not to
delete a struct before processing,
or saving, pointers stored within it.
The menu at left has examples of freeing all the memory used by a
list given through a
list pointer to its first element.
After memory is returned, it is unpredictable what their pointers
point to. For example, the following code:
produces:
(1 2 3 4 5)
(0 312372976 312372944 312372912 312372880)
Suppose we want to free the memory for all of the items on this
list:
- 1. Save a pointer to the head:
- 2. Advance the pointer past the head:
- 3. Delete the head and repeat:
The
delete operator returns the memory allocated by
new to the system's free storage (sometimes called the
"
heap").
Good programmers make sure that all memory allocated
with
new that is no longer needed is eventually returned
with
delete.
- The delete operator does not return a value, and is called
only for side effect.
- Judicious use of new and delete
manually implements the garbage collection performed
automatically by languages such as Racket and Java.
delete can be used with both dynamically created arrays and
dynamically created structs.
An example using
delete for an array is shown below:
Since the elements of an array are stored contiguously in memory,
and since the size of the array was given at the time of its
creation, using
delete on the array in this way will free all
the memory allocated for the array.
An example using
delete for a struct is shown below.
The operand must be a pointer to a struct.
Note that only the memory pointed to
by the operand is freed. If the operand points to another struct,
as with lists, that struct has to be separately freed as well.