Why smart pointers?

This is about smart pointers in C++. Of course, the first question is, what makes smart pointers “smart” and normal pointers so “dumb”?

Consider the following code

struct foo {
int* bar;
};

int main() {
foo* baz;
baz = new foo();
baz->bar = new int(5);

// do some stuff here

delete baz->bar;
delete baz;
}

That wasn’t too hard. Now consider this

foo* baz, *zap, *paz;
baz = new foo();
zap = new foo();
paz = new foo();
baz->bar = new int(5);
zap->bar = new int(6);
paz->bar = new int(7);

// Do some other stuff

// now call all the deletes
//... or let them just leak memory :P

...

Clearly, writing delete for each and every piece of memory allocated quickly becomes a pain. Wouldn’t it be wonderful to have a automagick thing which ‘deletes’ everything we allocated (aka a garbage collector like thing)?

Well, be happy, smart pointers can be of help here. What smart pointers does follows the concept of RAII


RAII

So what’s RAII now? Here’s a link to wiki which explains what it is, formally. It is just a technique which assures you that the destructor of the object will be called, even if an exception occurs, and generally, when the object goes out of scope.

Enough with rambling, onto example code

class ExampleClass {
Resource R;
public:
ExampleClass() { } /* Will initialize the resource R */
... do some work here
~ExampleClass() { } /* Destructor reached, R will be destroyed/ released */
};

int main() {
ExampleClass object; // resource R is initialized;
... stuff happens

return 0;
} // object goes out of scope, R will be released, since destructor of object is called.

Easy, isn’t it? The programmer does not have to explicitly manage the resource – lesser bugs and headaches. 🙂

Right. How does smart pointers fit in here? Our aim is the same as in the earlier case, let the resource (in this case, memory allocated to pointer) be released when user does not want it anymore, without user having to explicitly do it.

There are a number of smart pointers, in which we see one of them right now – the std::shared_ptr.
The shared pointer is a reference counted pointer, which increments its count every time a copy is made. Once the reference count comes down to 0, the resource gets released. [ Come to think of it, isn’t it pure genius? These are things that make me feel as if I know nothing. ]

The declaration part is very easy, it goes like this
std::shared_ptr ptr;

A simple example follows

int main() {
std::shared_ptr ptr(new int(5));
std::cout << *ptr;
ptr.reset(new int(6));
std::cout << *ptr;
return 0;
}

Its mostly self explanatory, ptr is declared. Later on we replace it with another value by resetting it. [ As a fun exercise, you could try running this program through valgrind, to actually check if it is really free of memory leaks. ]

cppreference gives a good overview of all the details of shared_ptr.

Advertisements
Standard