![]() |
|||||||||
2.9 Dynamic Objects |
|||||||||
Dynamic objects have lifetimes unbounded by the existence of the scope in which they were created. Thus, objects can be constructed in a function that continue to exist after the function returns; or objects can be created in an if-then construct that exists after the if-then construct has been executed. Dynamic objects give the programmer greater flexibility in managing objects. However, the programmer also assumes greater responsibility for insuring that dynamic objects are managed properly. Two problems that can occur with dynamic objects are destructing the object too soon and failing to destruct the objects at all. A dynamic object is created using a "new" operator that returns a pointer to the newly constructed object and is destructed by a "delete" operator. A pointer variable is used to hold the pointer to the object that is returned by the new operator. The delete operator takes a pointer variable as an operand and destructs the object pointed to by that variable. The following example illustrates how dynamic objects can be created and deleted.
Frame *window, *view; // declaration of pointer variables
window = new Frame("First", 10, 20, 50, 50); // create a new Frame object
view = new Frame("Second",70, 20, 50, 50); // create a new Frame object
Frame *edit = new Frame ("Editor", 50, 75, 100, 100); // combine declaration of pointer
// variable and object construction
Frame *default = new Frame; // use default constructor values
delete window; // destruct window Frame
delete view; // destruct view Frame
delete edit; // destruct edit Frame
delete default; // destruct default Frame
In this example, window and view are declared as variables that point to Frame objects. It is important to realize that this declaration does not create two frames; it merely creates two variables that will point to Frame objects that are created sometime in the future. The two Frame objects are then created and the variables "window" and "view" are set pointing to these objects. The declaration of the pointer variable and the construction of the object to which it points can be combined in a single statement as shown with the edit and default. Finally, the four Frame objects are deleted. Notice the syntax of creating dynamic objects. The name of the class appears immediately after the keyword "new." The constructor arguments, if any, are given in parentheses after the name of the class. When there are no constructor arguments, the parenthesis are omitted as shown in the creation of the default object. An operation is applied to a dynamic object using the -> operator. This "arrow" operator is two adjacent characters, a minus sign and a greater than symbol. An exaple of operating on a dynamic object is the following:
Frame* display = new Frame ("A Display", 10, 20, 100, 200);
display->MoveTo(50, 50);
display->Resize(200, 200);
In this example the display object is moved and resized using the arrow operator to apply the corresponding methods. Two types of serious errors can occur if dynamic objects are not used properly. These errors are serious in two senses. First, the errors can cause the program to abort or exhibit unpredictable behavior. Second, in real programs, the causes of these errors are among the hardest to find. The first type of error that can occur with dynamic objects is deleting a dynamic object too soon. The example below shows a situation where a Frame object is pointed to by two different variables, display and view. The shared object is destructed by the "delete display;" statement. The error then occurs when, using the view variable, an attempt is made to operate on the now destructed object.
Frame *display = new Frame ("Shared", 10, 20, 100, 100);
Frame *view;
view = display; // both point to same Frame object
display->MoveTo(50, 50); // OK - moves shared Frame object
view->Resize(200, 200); // OK - resizes shared Frame object
delete display; // delete shared object
view->MoveTo(20, 20); // ERROR - object already deleted!
The best outcome of using already-deleted objects is that the program aborts. In this case, the debugging can usually begin at or very close to the actual point of the error. However, and much worse, the program may continue to execute. The run-time system may not be able to detect that the object is deleted and will proceed to alter the memory previously occupied by the object. The effects of this are unpredictable. Often, some other part of the program will discover that an object has mysteriously been damaged. Finding the source of this problem in a large program is extremely difficult. The second type of error that can occur with dynamic objects is not deleting a dynamic object that is no longer accessible. This type of error is referred to as a "memory leak" because the pool of available memory appears to be leaking away. In a long-running program (air-traffic control, electronic funds transfer, etc.), sufficient memory can be leaked away so that the program aborts. Severe memory leaks can cause hundreds of megabytes of memory to be leaked. An example of a memory leak is shown in the example below.
Frame *display;
for (int i=0; i<100; i++) {
display = new Frame ("Memory Leak", 50, 50, 100, 100);
// display used but not deleted
}
In this example, 100 Frame objects are created but none of them are deleted though all but the last of these Frame objects are inaccessible because the pointer to them has been overwritten. However, the memory to hold these objects is still allocated. To the run-time system, the program is still using the memory, but the program has lost any means of finding the objects. Thus, the memory is allocated but inaccessible - it has leaked away. The errors in the two examples immediately above are easly identified because so little code is involved in each example. But imagine a program with tens of classes, hundreds of methods, and thousands of objects, where numerous objects are shared between various parts of the system. In these cases - the really important ones - it is extremely difficult to locate what causes these types of errors.
Tasks
|
|||||||||
|
|||||||||
ÿ