Pointers can be used to manage storage that is allocated manually while the program is
executing. The new
and delete
keywords allow this manual
allocation and de-allocation of memory in the C++ language. This facility
is very powerful. For example, we can create the memory space to manipulate an image or to open
a temporary record at any point in the code. This feature can, however, lead to serious
difficulties.
For an example of problems that can arise, see this code segment:
int main() { Account *a = new Account("John", 10.50, 123456); Account *b = new Account("Derek", 12.07, 123457); a->display(); b->display(); b = a; a->display(); b->display(); }
The full source code for this example is here -
AccountDynamicCreation.cpp
.
When run, this application gives the output as in Figure 3.12, “The Account Dynamic Allocation Example.”. The code
dynamically creates two Account
objects and assigns them to the
a
and b
Account
pointers. The
display()
method is called on both objects resulting in the display of
two account details, John and Derek's accounts. The assignment b = a;
is the key
problem here. The only reference we have to these two "anonymous" objects is the two pointers. If one
pointer is assigned to the other then any reference we had to the second object (Derek's account) is
lost. This results in the object being lost in memory, and not capable of being de-allocated.
This loss is called a memory leak. Since both pointers are now pointing at the same
Account
object, the same details will be displayed when the
display()
method is called on each pointer.
This can be further illustrated as in Figure 3.13, “The Account Dynamic Allocation Illustration.”.
After the assignment b=a
the pointer b
is pointing to the
first Account
object. The second object "Derek's" Account
has no reference or pointer and so is lost. The memory associated with this object will only be
deallocated (by the operating system) after the application has run to completion.
A further problem with the dynamic allocation/deallocation of data is that
the delete
call must be invoked by the programmer before the destructor of the
class is called. For example, when a destructor is added to the code segment above that simply
displays that an account is being destroyed (it could be doing
something important like creating a paper record), we could use the code:
int main() { Account *a = new Account("John",10.50, 123456); Account *b = new Account("Derek",12.07, 123457); a->display(); b->display(); b = a; delete a; // deletes John's account }
(The full source code for this example is here -
AccountDynamicCreationTest.cpp
).
Execution of the application will result in the output, as shown in Figure 3.14, “The Account Dynamic De-Allocation First Test.”:
So the destructor is called on the Account
object with John's details, but the
destructor is never called on the Account
object with Derek's details.
Suppose the code is altered to call a delete
on both pointers a
and b
, like:
int main() { Account *a = new Account("John",10.50, 123456); Account *b = new Account("Derek",12.07, 123457); a->display(); b->display(); b = a; delete a; // deletes John's account delete b; // tries to delete John's account again }
(The full source code for this example is here -
AccountDynamicCreationTest2.cpp
- Caution, this
code when run may crash your computer.)
What would the output be? Well it would be as in Figure 3.15, “The Account Dynamic De-Allocation Second Test.”:
If you run this application on Microsoft Windows, Microsoft will apologise of the inconvenience for the error! You can tell them about the problem, but they probably don't really care!
So what is the problem? Well since both pointers a
and b
point at the same Account
object, the first delete
call deletes the object referenced by the pointer (John's account), but the second call to delete
tries to delete something that is not there (John's account again), thus causing the crash.
When applying delete
to a pointer to an object, it calls the
destructor for the object before releasing its storage.
© 2006
Dr. Derek Molloy
(DCU).