Further Pointer Pathology with Heap Memory

The result of applying delete to a pointer that holds the address of a valid object in the heap is to change the status of that heap memory from "in use" to "available." After delete has been applied to a pointer, the state of that pointer itself is undefined. The pointer may or may not still store the address of that deleted memory, so a second application of delete to the same pointer may cause run-time problemspossibly heap corruption.

In general, the compiler cannot detect attempts to apply delete repeatedly to the same object, especially if that piece of memory (or a part thereof) has since been reallocated. To help avoid the very undesirable consequences of a repeated delete, it is good practice to assign NULL to a pointer immediately after it has been deleted.

If delete is applied to a null pointer, there is no action and no error.

Applying delete to a non-null pointer that was not returned by new produces undefined results. In general, the compiler will not be able to determine whether the pointer was or was not returned by new, so undefined run-time behavior can result. Bottom line: It is the programmer's responsibility to use delete correctly.

One of the richest sources of run-time errors is the production of memory leaks. A memory leak is produced when a program causes memory to be allocated and then loses track of that memory so that it can neither be accessed nor deleted. An object that is not properly deleted will occupy memory until the process terminates.

Some programs (e.g., operating systems) stay active for a long time. Suppose such a program contains a frequently executed routine that produces a memory leak each time it is run. The heap will gradually become perforated with blocks of inaccessable, undeleted memory. At some point a routine that needs a substantial amount of contiguous dynamic memory may have its request denied. If the program was not expecting an event like that, it may not be able to continue.

The operators new and delete give the C++ programmer increased power as well as increased responsibility.

Here is some sample code that illustrates a memory leak. After defining a couple of pointers, memory will look a little like Figure 22.1.

int* ip = new int; // allocate space for an int
int* jp = new int(13); // allocate and initialize
cout << ip << '	' << jp << endl;

Figure 22.1. Initial values of memory

Now we add one more line of code.

jp = new int(3); // reassign the pointer - MEMORY LEAK!!

After executing the single line above, our memory looks like Figure 22.2.

Figure 22.2. Memory after leak

Example 22.3. src/pointers/pathology/pathologydemo1.cpp

#include 
using namespace std;

int main() {
 int* jp = new int(13); <-- 1
 cout << jp << '	' << *jp << endl;
 delete jp;
 delete jp; <-- 2
 jp = new int(3); <-- 3
 cout << jp << '	' << *jp << endl;
 jp = new int(10); <-- 4
 cout << jp << '	' << *jp << endl;
 int* kp = new int(17);
 cout << kp << '	' << *kp << endl;
 return 0;
}

Output:

OOP> g++ pathologydemo1.cpp
OOP> ./a.out
0x8049e08 13
0x8049e08 3
0x8049e08 10
Segmentation fault
OOP>
 

(1)allocate and initialize

(2)error: pointer already deleted

(3)Reassign the pointerMEMORY LEAK!

(4)Reassign the pointerMEMORY LEAK!

In Example 22.3, we deleted the pointer jp twice. The second deletion is a serious error but the compiler did not catch it. That error corrupted the heap, made any further memory allocation impossible, and made the behavior of the program beyond that point undefined. For example, notice that when we attempted to produce a memory leak by reassigning the pointer jp, we did not get any new memory. When we attempted to introduce another pointer variable we got a segmentation fault. This is all undefined behavior and may be different on another platform or with another compiler.


Part I: Introduction to C++ and Qt 4

C++ Introduction

Classes

Introduction to Qt

Lists

Functions

Inheritance and Polymorphism

Part II: Higher-Level Programming

Libraries

Introduction to Design Patterns

QObject

Generics and Containers

Qt GUI Widgets

Concurrency

Validation and Regular Expressions

Parsing XML

Meta Objects, Properties, and Reflective Programming

More Design Patterns

Models and Views

Qt SQL Classes

Part III: C++ Language Reference

Types and Expressions

Scope and Storage Class

Statements and Control Structures

Memory Access

Chapter Summary

Inheritance in Detail

Miscellaneous Topics

Part IV: Programming Assignments

MP3 Jukebox Assignments

Part V: Appendices

MP3 Jukebox Assignments

Bibliography

MP3 Jukebox Assignments



An Introduction to Design Patterns in C++ with Qt 4
An Introduction to Design Patterns in C++ with Qt 4
ISBN: 0131879057
EAN: 2147483647
Year: 2004
Pages: 268

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net