Interpreting an Object Dump

The preceding dump comes from the original memory checkpoint example in the section “Detecting a Memory Leak” on page 292. Remember that there were only two explicit allocations in that program—one on the frame and one on the heap:

// do your memory allocations and deallocations ...

CString s = "This is a frame variable";

// the next object is a heap object

CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );

Start with the CPerson object; its constructor takes three arguments that are pointers to char. The constructor uses those arguments to initialize CString member variables for the CPerson class. In the memory dump, you can see the CPerson object listed along with three nonobject blocks (3, 4, and 5) that hold the characters for the CString member variables. These memory blocks will be deleted when the destructor for the CPerson object is invoked.

Block number 2 represents the CPerson object itself. After the CPerson address listing, the contents of the object are displayed. This is a result of DumpAllObjectsSince calling the Dump member function for the CPerson object.

You can guess that block number 1 is associated with the CString frame variable because of its sequence number and its size, which matches the number of characters in the frame CString variable. The allocations associated with frame variables are automatically deallocated when the frame variable goes out of scope.

In general, you shouldn't worry about heap objects associated with frame variables because they are automatically deallocated when the frame variables go out of scope. In fact, you should position your calls to Checkpoint so that they are outside the scope of frame variables to avoid clutter in your memory diagnostic dumps. For example, place scope brackets around the previous allocation code, as shown here:

oldMemState.Checkpoint();

{

// do your memory allocations and deallocations ...

CString s = "This is a frame variable";

// the next object is a heap object

CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );

}

newMemState.Checkpoint();

With the scope brackets in place, the memory dump for this example is as follows:

Dumping objects ->

{5} string.cpp(62) : non-object block at $00A7521A, 9 bytes long

{4} string.cpp(62) : non-object block at $00A751F8, 5 bytes long

{3} string.cpp(62) : non-object block at $00A751D6, 6 bytes long

{2} a CPerson at $51A4

Last Name: Smith

First Name: Alan

Phone #: 581-0215

Notice that the memory block associated with the CString frame variable has been deallocated automatically and does not show up as a memory leak. The automatic deallocation associated with scoping rules takes care of most memory leaks associated with frame variables.

For objects allocated on the heap, however, you must explicitly delete the object to prevent a memory leak. To clean up the last memory leak in the previous example, you can delete the CPerson object allocated on the heap, as follows:

{

// do your memory allocations and deallocations ...

CString s = "This is a frame variable";

// the next object is a heap object

CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );

delete p;

}