Online Book Reader

Home Category

Professional C__ - Marc Gregoire [378]

By Root 1349 0
from shared_ptr\shared_ptr_double_delete.cpp

If you were to create two standard shared_ptrs and have them both refer to the same Nothing object as follows, both smart pointers would attempt to delete the same object when they go out of scope:

void doubleDelete()

{

Nothing* myNothing = new Nothing();

shared_ptr smartPtr1(myNothing);

shared_ptr smartPtr2(myNothing);

}

Code snippet from shared_ptr\shared_ptr_double_delete.cpp

The output of the previous function would be:

Nothing::Nothing()

Nothing::~Nothing()

Nothing::~Nothing()

Yikes! One call to the constructor and two calls to the destructor? You will get exactly the same result with the unique_ptr template and with the old deprecated auto_ptr smart pointer. You might be surprised that even the reference-counted shared_ptr class behaves this way. However, this is correct behavior according to the C++11 standard. You should not use shared_ptr like in the previous doubleDelete() function to create two shared_ptrs pointing to the same object. Instead, you should simply use the assignment operator as follows:

void noDoubleDelete()

{

Nothing* myNothing = new Nothing();

shared_ptr smartPtr1(myNothing);

shared_ptr smartPtr2 = smartPtr1;

}

Code snippet from shared_ptr\shared_ptr_double_delete.cpp

The output of this code is:

Nothing::Nothing()

Nothing::~Nothing()

Even though there are two shared_ptrs pointing to the same Nothing object, the Nothing object is only destroyed once. Remember that unique_ptr is not reference counted. In fact, unique_ptr will not allow you to use the assignment operator as in the noDoubleDelete() function. That’s another reason to prefer shared_ptr instead of unique_ptr.

If your program uses smart pointers by copying them, assigning them, or passing them as arguments to functions, the shared_ptr is the perfect solution.

If you really need to write code as shown in the previous doubleDelete() function, you will need to implement your own smart pointer to prevent double deletion. You can also implement your own reference-counted smart pointer in case your compiler does not yet support shared_ptr. How to do this is shown in the next section. But again, it is recommended to use the standard shared_ptr template and simply avoid code as in the doubleDelete() function, and use assignment instead:

shared_ptr smartPtr2 = smartPtr1;

The SuperSmartPointer

This section explains how to write your own reference-counting smart pointer that you can use to solve the double deletion problem from the doubleDelete() function in the previous section.

The approach for the SuperSmartPointer, a reference-counting smart pointer implementation is to keep a static map for reference counts. Each key in the map is the memory address of a traditional pointer that is referred to by one or more SuperSmartPointers. The corresponding value is the number of SuperSmartPointers that refer to that object.

The implementation of SuperSmartPointer that follows is based on the smart pointer code shown in Chapter 18. You may want to review that code before continuing. The major changes occur when a new pointer is set (through the single argument constructor, the copy constructor, or operator=) and when a SuperSmartPointer is finished with an underlying pointer (upon destruction or reassignment with operator=).

On initialization of a new pointer, the initPointer() method checks the static map to see if the pointer is already contained by an existing SuperSmartPointer. If it is not, the count is initialized to 1. If it is already in the map, the count is bumped up. When the pointer is reassigned or the containing SuperSmartPointer is destroyed, the finalizePointer() method is called. This method throws an exception if the pointer is not found in the map. If the pointer is found, its count is decremented by one. If this brings the count down to zero, the underlying pointer can be safely released. At that time, the key/value pair is explicitly removed from the map to keep the map size down:

template

Return Main Page Previous Page Next Page

®Online Book Reader