Using Boost for managing a list of pointers

One of the popular uses of the Standard Template Library (STL) in the C++ language is to manage a dynamic list of pointers. For example, if you have a rendering system for your game which works with a common base object that every drawable object is derived from.

If you were using STL, then typically you would create something like the following:

#include <iostream>
#include <list>

using namespace std;

class IRenderObj
{
public:
float x;
float y;
float z;
};

main()
{
list<IRenderObj*> drawList;
list<IRenderObj*>::iterator drawListIter;

IRenderObj *a= new IRenderObj;
IRenderObj *b= new IRenderObj;
IRenderObj *c= new IRenderObj;

a->x = 0.0f; a->y = 0.0f; a->z = 0.0f;
b->x = 0.0f; b->y = 1.0f; b->z = 0.0f;
c->x = 1.0f; c->y = 0.0f; c->z = -10.0f;

drawList.push_back(a);
drawList.push_back(b);
drawList.push_back(c);

for (drawListIter = drawList.begin();
drawListIter != drawList.end();
drawListIter++)
{
//draw, translate each vector
glTranslatef( (*drawListIter)->x, (*drawListIter)->y, (*drawListIter)->z );

}

// Now Free pointers
for (drawListIter = drawList.begin();
drawListIter != drawList.end();
drawListIter++)
{
delete *drawListIter;
}

drawList.clear(); // List is deleted.

}

Not bad, not bad. It’s just a bit of a pain to remember to manually go through the list to delete each object. It’s manageable if you only have a few of these such lists, but even then you have to be supremely careful that you remember to do it. In short, there’s a chance of creating a memory leak.

Using Boost::ptr_list

Another approach is to use a component of the Boost C++ libraries, boost::ptr_list to manage your list of objects for you. With this object as your dynamic container, it will automatically clean things up for you.

#include <boost/ptr_container/ptr_list.hpp>
#include <iostream>

using namespace std;

class IRenderObj
{
public:
float x;
float y;
float z;
};

main()
{
//notice the declaration doesn’t require you to use a pointer to IRenderObj
boost::ptr_list<IRenderObj> drawList;
boost::ptr_list<IRenderObj>::iterator drawListIter;

IRenderObj *a= new IRenderObj;
IRenderObj *b= new IRenderObj;
IRenderObj *c= new IRenderObj;

a->x = 0.0f; a->y = 0.0f; a->z = 0.0f;
b->x = 0.0f; b->y = 1.0f; b->z = 0.0f;
c->x = 1.0f; c->y = 0.0f; c->z = -10.0f;

drawList.push_back(a);
drawList.push_back(b);
drawList.push_back(c);

for (drawListIter = drawList.begin();
drawListIter != drawList.end();
drawListIter++)
{
//draw, translate each vector
glTranslatef( (*drawListIter)->x, (*drawListIter)->y, (*drawListIter)->z );

}

//so far so good, the same as our STL code

//except the kicker…the clear method will clean up for us!
drawList.clear(); // All pointers held in list are deleted.

}

The choice is yours, but in this case I pretty much stick with Boost as it’s one less potential memory leak I have to worry about.




Leave a Reply

You can use these XHTML tags: <a href="" title=""> <abbr title=""> <acronym title=""> <blockquote cite=""> <code> <em> <strong>