C++

Memory Leaks

Another way you might inadvertently create a memory leak is by reassigning your pointer before deleting the memory to which it points. Consider this code fragment:

1: unsigned short int * pPointer = new unsigned short int;

2: *pPointer = 72;

3: pPointer = new unsigned short int;

4: *pPointer = 84;

Line 1 creates pPointer and assigns it the address of an area on the free store. Line 2 stores the value 72 in that area of memory. Line 3 reassigns pPointer to another area of memory. Line 4 places the value 84 in that area. The original area—in which the value 72 is now held—is unavailable because the pointer to that area of memory has been reassigned. There is no way to access that original area of memory, nor is there any way to free it before the program ends.

The code should have been written like this:

1: unsigned short int * pPointer = new unsigned short int;

2: *pPointer = 72;

3: delete pPointer;

4: pPointer = new unsigned short int;

5: *pPointer = 84;

Now the memory originally pointed to by pPointer is deleted, and thus freed, in line 3.

NOTE: For every time in your program that you call new, there should be a call to delete. It is important to keep track of which pointer owns an area of memory and to ensure that the memory is returned to the free store when you are done with it.

Creating Objects on the Free Store

Just as you can create a pointer to an integer, you can create a pointer to any object. If you have declared an object of type Cat, you can declare a pointer to that class and instantiate a Cat object on the free store, just as you can make one on the stack. The syntax is the same as for integers:

Cat *pCat = new Cat;

This calls the default constructor—the constructor that takes no parameters. The constructor is called whenever an object is created (on the stack or on the free store).

Deleting Objects

When you call delete on a pointer to an object on the free store, that object’s destructor is called before the memory is released. This gives your class a chance to clean up, just as it does for objects destroyed on the stack. Listing 8.5 illustrates creating and deleting objects on the free store.

Listing 8.5. Creating and deleting objects on the free store.

1: // Listing 8.5

2: // Creating objects on the free store

3:

4: #include <iostream.h>

5:

6: class SimpleCat

7: {

8: public:

9: SimpleCat();

10: ~SimpleCat();

11 private:

12 int itsAge;

13 };

14

15 SimpleCat::SimpleCat()

16 {

17 cout << "Constructor called.\n";

18 itsAge = 1;

19 }

20

21 SimpleCat::~SimpleCat()

22 {

23 cout << "Destructor called.\n";

24 }

25

26 int main()

27 {

28 cout << "SimpleCat Frisky...\n";

29 SimpleCat Frisky;

30 cout << "SimpleCat *pRags = new SimpleCat...\n";

31 SimpleCat * pRags = new SimpleCat;

32 cout << "delete pRags...\n";

33 delete pRags;

34 cout << "Exiting, watch Frisky go...\n";

35 return 0;

36 }

Output:

SimpleCat Frisky...

Constructor called.

SimpleCat *pRags = new SimpleCat..

Constructor called.

delete pRags...

Destructor called.

Exiting, watch Frisky go...

Destructor called.

Analysis: Lines 6-13 declare the stripped-down class SimpleCat. Line 9 declares SimpleCat’s constructor, and lines 15-19 contain its definition. Line 10 declares SimpleCat’s destructor, and lines 21-24 contain its definition. In line 29, Frisky is created on the stack, which causes the constructor to be called. In line 31, the SimpleCat pointed to by pRags is created on the heap; the constructor is called again. In line 33, delete is called on pRags, and the destructor is called. When the function ends, Frisky goes out of scope, and the destructor is called.

Back to Index