|

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.
|