Smart pointer

Write a smart pointer class. A smart pointer is a data type, usually implemented with templates, that simulates a pointer while also providing automatic garbage collection. It automatically counts the number of references to a SmartPointer<T*> object and frees the object of type T when the reference count hits zero.

A smart pointer is the same as a normal pointer, but it provides safety via automatic memory management. It avoids issues like dangling pointers, memory leaks and allocation failures. The smart pointer must maintain a single reference count for all references to a given object.

This is one of those problems that seems, at first glance, pretty overwhelming, especially if you are not a C++ expert. One useful way to approach the problem is to divide the problem into two parts: (1) outline the pseudocode and approach and then (2) implement the detailed code.

In terms of the approach, we need a reference count variable that is incremented when we add a new reference to the object and decremented when we remove a reference. The code should look something like the below pseudocode:

C++:
template <class T> class SmartPointer{
 T* ref;
 unsigned* ref_count;
}
We know we need constructors and a single destructor for this class, so let’s add those first.
C++:
SmartPointer(T* object){
 /*We want to set the value of T* obj, and set the reference
   *counter to 1.*/
}
C++:
SmartPointer(SmarterPointer<T>& sptr){
 /*This constructor creates a new smart pointer that points to
   *an existing object. We will need to first set obj and
   *ref_count to pointer to sptr’s obj and ref_count. Then,
   * because we created a new reference to obj, we need to
   * increment ref_count.*/
}
C++:
~SmartPointer(SmarterPointer<T> sptr){
/* We are destroying a reference to the object. Decrement
 * ref_count. If ref_count is 0, then free the memory create by
 * the integer and destroy the object.*/
}
There is one additional way that references can be created: by setting one SmartPointer equal to another. We’ll want to override the equal operator to handle this, but for now, let’s sketch the code like this.
C++:
onSetEquals(SmartPointer<T> ptr1, SmartPointer<T> ptr2){
/* If ptr1 has an existing value, decrement its reference count.
 * Then, copy the pointers to obj and ref_count over. Finally,
 * since we created a new reference, we need to increment
 * ref_count.*/
}
Getting just the approach, even without filling in the complicated C++ syntax, would count for a lot. Finishing out the code is now just a matter of filling the details.
C++:
01 template <class T> class SmartPointer{
02   public:
03   SmartPointer(T* ptr){
04     ref=ptr;
05     ref_count=(unsigned*) malloc(sizeof(unsigned));
06     *ref_count=1;
07   }
08 
09   SmartPointer(SmartPointer<T>& sptr){
10     ref=sptr.ref;
11     ref_count=sptr.ref_count;
12     ++(*ref_count);
13   }
14   /* Override the equal operator, so that when you set one smart
15    * pointer equal to another the old smart pointer has its
16    * referece count decremented and the new smart pointer has its
17    * reference count incremented.*/
18   SmartPointer<T>& operator=(SmartPointer<T> &sptr){
19     /*If already assigned to an object, remove one reference.*/
20     if(*ref_count>0){
21       remove();
22     }
23     if(this!=&sptr){
24       ref=sptr.ref;
25       ref_count=sptr.ref_count;
26       ++(*ref_count);
27     }
28     return *this;
29   }
30 
31   ~SmartPointer(){
32     remove();
33   }
34   T getValue(){
35     return *ref;
36   }
37   protected:
38   void remove(){
39     (*ref_count);
40     if(*ref_count==0){
41       delete ref;
42       free(ref_count);
43       ref=NULL;
44       ref_count=NULL;
45     }
46   }
47   T* ref;
48   unsigned* ref_count;
49 };
Advertisements
This entry was posted in C++. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s