Update(May 20, 2007) — I have posted a short introduction to Boost smart pointers here.
Please Note: Smart pointer implementations other than auto_ptr<T> often use reference counting mechanisms(yes the reference counting mechanism is analogous to what you see in ObjC). I don’t talk about reference counting in C++ in this article, but I will probably talk about it in the future. I can point you to the freely available source code from the book Professional C++ here. This code demonstrates a reference-counting smart pointer implementation. I might make a few comments on the code later.
In Part II, I talked about some of the ways in which C++ differs from C. One of the complaints against C++(and C) is its manual memory management. The problems with manual memory management can be mitigated with the use of smart pointers and eliminated with a third-party garbage collector. However, garbage collectors introduce some overhead, and one has to download and ‘install’ the library. The built-in smart pointer class, auto_ptr<T> is not the fastest or best implementation of smart pointers, but it is “close enough for government work”. I probably said that I will go through the creation of classes in this iteration, but there are few C++ resources which talk about smart pointers and many that talk about class construction, so I will go through smart pointers first
There is nothing magical about smart pointers. If one understands how the stack and the heap work, then the basic premise behind smart pointers is easily understood. Here is my quick overview of the stack(Try Wikipedia for an overview of the heap for now)
(Warning: conceptual material ahead 🙂 Skip to the code if bored/confused.
The stack and the heap are two different buffers(set of memory locations in RAM). Programmers specify what will go on the stack when they actually write the program. For example , when you say int x = 0; you are adding the variable x to the stack(actually to the function’s activation record(aka stack frame), which is on the stack). What is an activation record? When I call a function say, for example z = sum(x,y), an array of information is pushed onto the stack, including, (but probably not limited to) the function parameters, local variables, and return address. Here’s a nice picture(note that the stack “grows” to the bottom). The “ESP” denotes the stack pointer, which points to the “top” of the stack. i, j, and k are the parameters to the function. This picture shows how the stack looks like immediately after the function is called.
After the function starts executing , there has to be space for local variables:
Pictures courtesy of this link
So, the local variables are a, r, c, b, and w. After the function does its work, the activation record is “popped”. Okay, the old locations of a, r, c, etc. might still be the same for a short while after the activation record is popped, but the programmer is not supposed to try and use those memory locations after a function returns–because there might be another function’s local variables using the same memory locations. “Popping the activation record” is done by moving the Stack Pointer, ESP back to the top of the grey box(Previous Stack Contents).
Okay, how is this related to smart pointers. The scope of a local variable is the function in which it is defined. So an easy way to think about this is if you have a function foo:
int foo(int x, int y)
/* calculations here */
Then once the statement return one; is executed, and the } is reached, the activation record for foo(..) is popped. So a smart pointer works by “wrapping” a regular pointer inside a stack based object(the auto_ptr). Then when an auto_ptr smart pointer object is “popped”, the dynamically allocated memory which the “dumb pointer” points to is automatically deallocated , ostensibly by automatically calling delete on the dynamically allocated memory pointed to by the “dumb pointer”.
—END of potentially boring conceptual/background material———-
Here’s some code that shows how to use a smart pointer.
using namespace std;
string* new_str = new string(“hello world”);
auto_ptr < string > smrtstr(new_str);
cout<<“The string length is”<<smrtstr->length()<<endl;
//no need to call delete or anything.
Now, if you plan to use smart pointers for a real project, you should invest some time to install the Boost smart pointer library (the auto_ptr has some issues when dealing with Standard Template Library containers like vectors, maps, etc)