Simple Memory/Resource Management with Garbage Collection in C++

The Premise

We’ve all heard, contrary to what we c++ programmers know, how hard c++ is, and how much harder memory/resource management and garbage collection are in c++. But with a little help from the boost libraries, everything is possible, and downright easy.

Resource management and garbage collection are something that comes up fairly often in any situation.  As we build programs, we always end up using memory and resources in one way or another. Whether we’re loading images, using web-cams, creating window dialogs, analyzing data or whatever else, things can quickly get out of hand if we don’t keep track of the resources we use and then return them back when we’re done using them. How many of you have nullified a pointer without releasing it first?

Of course, we could always search for a library. But as many of us know from experience, dealing with libraries is not always the easiest thing, and could lead to big changes in our code.

Our Objectives

In this article, we want to stick to a simple solution, and nothing more. Whistles and bells could always be added later if we really feel like it. Thus, for our resource manager, we want to do the following:

  1. Add/Remove resources
  2. Sort resources
  3. Don’t allow duplicates of resources
  4. Automatic release of resources not being used anymore

Dependencies

For our simple system, we’re going to use an std::set in combination with smart pointers from the boost library boost::shared_ptr

  1. std::set
    1. Allows the “sorted” insertion of resources using our algorithm of choice
    2. Lets us “find” a resource using our algorithm of choice
    3. Insertion/Removal/Find are logarithmic in time
  2. boost::shared_ptr
    1. Automatic release of our resources whenever we’re done using them
    2. Lets us validate resources (Has the resource been initialized?)

The code

Finally we get to meat. We define our resource manager in one header file using one class. We also use template metaprogramming as  our class needs to handle any type of resource.

The following code shows our class. I have used inline commenting, but feel free to ask questions.  You can simply copy and paste it into one header file in your project and it will work. In case you’re curious, I prefix my classes with bl which stands for BarbatoLabs.

//-------------------------------------------------------
// Only include this file once
#ifndef BL_RESOURCEMANAGER_HPP
#define BL_RESOURCEMANAGER_HPP
//-------------------------------------------------------

//-------------------------------------------------------
template<typename blType>
class blResourceManager
{
public: // Constructors and Destructors

    // Default constructor
    blResourceManager();

    // Copy constructor
    blResourceManager(const blResourceManager<blType>& ResourceManager);

    // Virtual destructor
    ~blResourceManager()
    {
    }

public: // Public functions

    // Function used to add a resource to the manager
    void            AddResource(const shared_ptr<blType>& ResourceToAdd);

    // Function used to remove a resource from the manager
    void            RemoveResource(const shared_ptr<blType>& ResourceToRemove);

    // Functions used to get/set the resource vector
    const set<shared_ptr<blType> >&         GetResourceSet()const;

protected: // Protected Variables

    // Vector holding all resources
    set< shared_ptr<blType> >               m_Resources;
};
//-------------------------------------------------------

As can be seen, we have an std::set holding our resources, which also keeps a sorted list of the shared_ptr pointers, and does not allow duplicates. If you do want to allow duplicates, then use std::multiset instead of std::set.

Now it’s a simple manner of defining the class constructors, destructor, and functions. Remember that these have to be defined in the same header file since we’re using templates.

//-------------------------------------------------------
template<typename blType>
inline blResourceManager<blType>::blResourceManager()
{
}
//-------------------------------------------------------

//-------------------------------------------------------
template<typename blType>
inline blResourceManager<blType>::blResourceManager(const blResourceManager<blType>& ResourceManager)
{
    // Copy the resource vector
    this->m_Resources = ResourceManager.GetResourceVector();
}
//-------------------------------------------------------

//-------------------------------------------------------
template<typename blType>
inline const set<shared_ptr<blType> >& blResourceManager<blType>::GetResourceSet()const
{
    return this->m_Resources;
}
//-------------------------------------------------------

//-------------------------------------------------------
template<typename blType>
inline void blResourceManager<blType>::AddResource(const shared_ptr<blType>& ResourceToAdd)
{
    this->m_Resources.insert(ResourceToAdd);
}
//-------------------------------------------------------

//-------------------------------------------------------
template<typename blType>
inline void blResourceManager<blType>::RemoveResource(const shared_ptr<blType>& ResourceToRemove)
{
    this->m_Resources.insert(ResourceToRemove);
}
//-------------------------------------------------------

#endif // BL_RESOURCEMANAGER_HPP

Usage

To use this little gem, it’s very easy.  Here are some examples:

#include "blResourceManager.hpp"

int main(int argc, char *argv[])
{
    // Create a resource manager
    blResourceManager<int> MyManager;

    // Create and then add a resource to it
    shared_ptr<int> MyInt = boost::make_shared<int>(10);
    MyManager.AddResource(MyInt);

    // Create and add a resource to it all in one step
    MyManager.AddResource(boost::make_shared<int>(100));
}

Alternatives

Instead of std::set, we could use std::multiset which would allow for duplicate resources in our manager.

About Vincenzo Barbato

Known to his friends as Enzo, he's an outside-the-box engineer/researcher whose interests and expertise span many fields, including controls systems, multi-physics simulations, mechatronics, oil technologies, data analysis and machine vision just to name a few.

Refusing to grow up, he's on a continuous journey to develop simple and creative solutions that have the power of disrupting industries by optimizing systems and processes.

Married to a beautiful wife, with two beautiful daughters and two identical twin boys, his home is a never ending chaotic fountain of inspiration.

His outlook on life:

"Never blindly accept what you're told, listen, but then question, with curiosity, creativity and collaboration we can change the world"

About Enzo

Known to his friends as Enzo, he's an outside-the-box engineer/researcher whose interests and expertise span many fields, including controls systems, multi-physics simulations, mechatronics, oil technologies, data analysis and machine vision just to name a few. Refusing to grow up, he's on a continuous journey to develop simple and creative solutions that have the power of disrupting industries by optimizing systems and processes. Married to a beautiful wife, with two beautiful daughters and two identical twin boys, his home is a never ending chaotic fountain of inspiration. His outlook on life: "Never blindly accept what you're told, listen, but then question, with curiosity, creativity and collaboration we can change the world"

Leave a Reply

Your email address will not be published. Required fields are marked *