user1462192
user1462192

Reputation: 1105

about this smart pointer class

I run into this code in a book, a simple smart pointer, have a few questions about it:

    template <class T>
class SmartPointer {
 public:
    SmartPointer(T * ptr) {
        ref = ptr;
        ref_count = malloc(sizeof(unsigned));
        *ref_count = 1;
    }
    SmartPointer(SmartPointer<T> & sptr) {
        ref = sptr.ref;
        ref_count = sptr.ref_count;
        ++*ref_count;
    }
    SmartPointer<T> & operator=(SmartPointer<T> & sptr) {
        if (this != &sptr) {
           ref = sptr.ref;
           ref_count = sptr.ref_count;
           ++*ref_count;
        }
        return *this;
    }
    ~SmartPointer() {
        --*ref_count;
        if (*ref_count == 0) {
           delete ref;
           free(ref_count);
           ref = ref_count = NULL;
        }
    }
    T* operator->() { return ref; }
    T& operator*() { return *ref; }
 protected:
    T * ref;
    unsigned * ref_count; 
};

here are my questions: 1. why is the ref_count initialized by using malloc? why can't it be ref_count = new unsigned(); 2. the = operator function, doesn't it need to clean up the old value? this code seems to cause a ref counting error.

Thanks,

Upvotes: 0

Views: 127

Answers (3)

Puppy
Puppy

Reputation: 146910

This is bad code. Self-assignment is non-idiomatic, awful use of malloc, buggy reference counting implementation, no const on the copy assignment operator/constructor argument, and doesn't deal with SmartPointers that point to NULL. Throw your book away and get one that works.

Upvotes: 1

Alexander Chertov
Alexander Chertov

Reputation: 2108

This book you have is rubbish. You need to throw it away. This code doesn't even compile.

  1. malloc is not any better than new unsigned(1). malloc() returns void* which needs to be cast to unsigned* which is obviously not done here.
  2. You are right, the reference count of the object previously pointed to needs to be taken care of.

Why not try looking into the implementation of boost::shared_ptr or std::shared_ptr? It's very likely that you'll end up using it anyway.

Upvotes: 3

Alok Save
Alok Save

Reputation: 206528

why is the ref_count initialized by using malloc?

It can use std::new as well. The primary difference between new and malloc is that new provides an opportunity to suitably initialize your object by calling its constructor in addition to allocating dynamic memory.In case of in-built data type like unsigned int(as in your example code) essentially this important difference doesn't matter.
Note that usually std::new implementations also essentially call a malloc for memory allocation.

The = operator function, doesn't it need to clean up the old value? this code seems to cause a ref counting error

Indeed there is an error.
The = operator in this implementation checks if the pointer is being assigned to itself and if yes it correctly increases the reference count by 1, Since there is one more entity which shares this pointer after the = is called.
If the scenario is not self assignment then the implementation should reduce the reference count of the pointer being assigned to by 1, check if the count is 0 and if it is zero, deallocate the same.

Upvotes: 1

Related Questions