Saturday, December 22, 2012

Funny Boost

I located some examples I made when I first got acquainted with Boost and wanted to push the limits of the tutorials. Imagine the following two flavors of a program:
#include <boost/smart_ptr/shared_ptr.hpp>
using namespace std;
using namespace boost;
struct Thing {
public :
    Thing(int *i);
    void dumpP() {cout << pInt.get() << endl;}
private:
    shared_ptr<int> pInt;
};
Thing::Thing(int *i) : pInt(i) {
}
int _tmain(int argc, _TCHAR* argv[])
{
    int i;
    Thing t(&i);
    cout << &i << endl;
    t.dumpP();
   
    std::cin >> i;

    return 0;
}
 And
#include <boost/smart_ptr/shared_ptr.hpp>
using namespace std;
using namespace boost;
struct Thing {
public :
    Thing(int *i);
    void dumpP() {cout << pInt.get() << endl;}
private:
    shared_ptr<int> pInt;
};
Thing::Thing(int *i) : pInt(i) {
}
int _tmain(int argc, _TCHAR* argv[])
{
    int *j = new int(1);
    Thing t(j);
    cout << j << endl;
    t.dumpP();

    std::cin >> *j;

    return 0;
}
We see that their only difference is the fact that in the first version we use a local variable and in the second we allocate memory. Both are syntactically correct and both compile. However, one of them crashes before finishing execution.

If your guts tell you it is the one that uses dynamic memory, it is betraying you. The one that fails is the version that uses the local variable. What's the harm?

When they are deleted, Boost "intelligent" pointers free the object they reference if they are the last referencing pointer. This assumes the pointer is a dynamically-allocated variable. Since in the first version the variable is contained in the stack and has no valid dynamic memory block pointers, this crashes the program when it tries to free that part of the memory. This also explains why the last version works.

No comments:

Post a Comment