Search code examples
c++shared-ptrsmart-pointersdoubly-linked-listreference-counting

The advantage of reference linking over reference counting when implementing smart pointer?


The advantage of reference linking over reference counting is that the former does not use extra free store, which makes it more reliable: Creating a reference-linked smart pointer cannot fail. The disadvantage is that reference linking needs more memory for its bookkeeping (three pointers versus only one pointer plus one integer). Also, reference counting should be a bit speedier—when you copy smart pointers, only an indirection and an increment are needed. The list management is slightly more elaborate. In conclusion, you should use reference linking only when the free store is scarce. Otherwise, prefer reference counting.

This is a quote from Modern C++ Design: Generic Programming and Design Pattern Applied. I do not understand why reference linking based smart pointer does not use extra free store and then become more reliable i.e. never fail? Could anyone provide a bit explanation on this? Thanks!


Solution

  • When you declare a reference counted smart pointer as an automatic variable and allocate storage from free store for it to manage, even though the pointer's member variables will be on automatic storage, the control block created for book keeping and managing the object would be on the free store. A trivial example:

    class RefCountIntPtr {
        int *pointee;
        int *count;
    
    public:
        RefCountIntPtr(int *x) {
            if (x) {
                pointee = x;
                // allocate an int from free store and assign 1 to it
                count = new int(1);
            }
        }
    };
    
    int main() {
        RefCountIntPtr sp;
    }
    

    Here, sp's pointee and count would get allocated on the stack while what count is going to point to will be allocated on the heap. Assuming that the implementation (compiler) uses a heap for free store and stack for automatic storage.

    On the other hand, reference linked smart pointers have no control block allocation from free store, all they have are three pointers as member variables, all of them are allocated on auto storage. Creating more of them? No problem, they will all be in auto storage, acting as a linked list when you make them point to the same pointee. The difference is that instead of having an explicit count, the linked list acts as an implicit one, when all links vanish, we know that the count is 0 and the pointee needs to be freed.

    The reason for the comment on reliability is that when you allocate from free store there's higher probability that it'll leak during an exceptional scenario. However automatic variable allocation is much more reliable as deallocation is automatically handled by the compiler. See Why should C++ programmers minimize use of 'new'? for details.