Monday, 1 June 2009

A look at Smart Pointers

There is lot of confucion, misconceptions and misunderstanding regarding smart pointers. After looking at various books and tutorials, i got quite confused till I managed to figure out what they exactly are:

Smart pointers are objects that look and feel like pointers, but are smarter.

To look and feel like pointers, smart pointers need to have the same interface that pointers do: they need to support pointer operations like dereferencing (operator *) and indirection (operator ->). An object that looks and feels like something else is called a proxy object, or just proxy.

To be smarter than regular pointers, smart pointers need to do things that regular pointers don't. What could these things be? Probably the most common bugs in C++ (and C) are related to pointers and memory management: dangling pointers, memory leaks, allocation failures and other joys. Having a smart pointer take care of these things.

The simplest example of a smart pointer is auto_ptr, which is included in the standard C++ library. You can find it in the header , or take a look at Scott Meyers' auto_ptr implementation. Here is part of auto_ptr's implementation, to illustrate what it does:

template <class T> class auto_ptr

T* ptr;
auto_ptr(T* p = 0) : ptr(p) {}
auto_ptr() {delete ptr;}
T& operator*() {return *ptr;}
T* operator->() {return ptr;}
// ...

As you can see, auto_ptr is a simple wrapper around a regular pointer. It forwards all meaningful operations to this pointer (dereferencing and indirection). Its smartness in the destructor: the destructor takes care of deleting the pointer.

Lets look at a proper example:


using namespace


string name;
A(string n): name(n)

cout<<"Constructor of A = "<<name.c_str()<<" called "<<endl;
data = new(int);

A(string n, int x): name(n)

cout<<"Overloaded Constructor of A = "<<name.c_str()<<" called "<<endl;
data = new(int);
data = x;

cout<<"Destructor of A = "<<name.c_str()<<" called "<<endl;
data = this->data;
data = NULL;

A* operator ->() { return this;};


auto_ptr<A> a1(new A("a1"));
cout<<"Enter a number and press enter: ";
cin >> (*a1->data);
cout << "a1->data = "<<*a1->data<<endl;

A a2("a2",25);
A *a3 = new A("a3");


cout<<"Before SomeFunc()"<<endl;
cout<<"After SomeFunc()"<<endl;
The output is as follows:

As you have probably noticed, the instance a3 is never deleted and will cause memory leaks. Using smart pointer would automatically delete the instance a3 and the memory associated with it.

You can read Smart Pointers in much more detail at the References below.


No comments:

Post a Comment