Memory Management
Using new and delete
Basic Memory Management
When your program begins execution, it is assigned space
in memory by the operating system which is divided into three
parts:
- Your executable code
- The stack
- The heap
The stack is used to hold automatic variables declared inside your program,
function arguments, function return addresses, unnamed temporary
variables, and whatever else the compiler needs. This memory space
is managed by the operating system and code generated by the
compiler in your program. Stack space is assigned to your variables
when they are declared, and the stack space is automatically
reclaimed when your variables go out of scope.
The heap is the area in memory resevered for dynamically allocated
variables. The heap memory space must
be managed by code written by you in your program.
Your code must request the heap space for dynamically allocated variables
and must give back the heap space when the dynamically allocated variable
is no longer needed.
The size of the heap is finite. If too many dynamically
allocated variables are created, your program will exhaust the heap
memory space and your program will abort. When heap memory is
allocated but never freed, we say a memory leak has occurred.
In C, we used the functions malloc( ) and free( ) to
manage the heap. In C++, these functions are replaced by the operators
new and delete.
new and delete
A single unnamed dynamically allocated variable is created using the
operator new as in the code below
class Car
{
public:
Car( );
Car (const string& color, int miles);
. . . .
private:
string m_color;
int m_mileage;
};
Car *carPtr;
carPtr = new Car;
which is represented by this diagram
When a new object is created, the default constructor for that
object is called unless a specific constructor is specified as shown here
Car *carPtr2 = new Car( "Red", 4500 );
To return this memory to the heap, use the delete
operator as in the following code.
delete carPtr;
Note that this statement frees the memory pointed to by
carPtr. It DOES NOT alter the contents of the
carPtr variable. A good "defensive programming" technique is to clear
the contents of a pointer variable after using delete. This code
is better
delete carPtr;
carPtr = 0;
Having multiple pointer variables point to the same memory is dangerous
(although not necessarily wrong). Consider this example closely
int *soup, *salad;
soup = new int( 42 );
salad = soup;
delete soup;
soup = 0;
What does this picture of memory look like?
What's the potential problem?
How do we address this problem?
delete soup;
What does this picture of memory look like?
What's the potential problem?
new and delete with arrays
The new operator can also be used to allocate
arrays of variables. In this case, the size of the array
must be specified. The default constructor for each element
of the array is called if no other constructor is specified.
int *intPtr;
Car *carPtr;
intPtr = new int[ 7 ];
carPtr = new Car[ 44 ];
carPtr2 = new Car[ 33 ] ("green", 1234);
// code to use intPtr and carPtr
delete [ ] intPtr;
delete [ ] carPtr;
delete [ ] carPtr2;
Note the slightly different format for delete.
The brackets are required to avoid a memory leak.
Summary
- Program memory is divided into code, stack and heap segments
- Use new to dynamically allocate variables from the heap
- Use delete to return heap memory for reuse
- The forms of new and delete must match. You will
NOT recieve a compiler error if they don't match.
- Setting pointers to 0 after using delete is a good
defensive coding technique.
Last Modified: Monday, 28-Aug-2006 10:16:04 EDT