Reputation: 1105
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
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 SmartPointer
s that point to NULL. Throw your book away and get one that works.
Upvotes: 1
Reputation: 2108
This book you have is rubbish. You need to throw it away. This code doesn't even compile.
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.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
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