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:
  1. Your executable code
  2. The stack
  3. 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

  1. Program memory is divided into code, stack and heap segments
  2. Use new to dynamically allocate variables from the heap
  3. Use delete to return heap memory for reuse
  4. The forms of new and delete must match. You will NOT recieve a compiler error if they don't match.
  5. Setting pointers to 0 after using delete is a good defensive coding technique.


Last Modified: Monday, 28-Aug-2006 10:16:04 EDT