1
\$\begingroup\$

Dear all, this is going to be tough: I have created a game object factory that generates objects of my wish. However, I get memory leaks which I can not fix.

Memory leaks are generated by return new Object(); in the bottom part of the code sample.

static BaseObject * CreateObjectFunc()
{
    return new Object();
}

How and where to delete the pointers? I wrote bool ReleaseClassType(). Despite the factory works well, ReleaseClassType() does not fix memory leaks.

bool ReleaseClassTypes()
{
    unsigned int nRecordCount = vFactories.size();
    for (unsigned int nLoop = 0; nLoop < nRecordCount; nLoop++ )
    {
        // if the object exists in the container and is valid, then render it
        if( vFactories[nLoop] != NULL) 
            delete vFactories[nLoop]();
    }
    return true;
}

Before taking a look at the code below, let me help you in that my CGameObjectFactory creates pointers to functions creating particular object type. The pointers are stored within vFactories vector container.

I have chosen this way because I parse an object map file. I have object type IDs (integer values) which I need to translate them into real objects. Because I have over 100 different object data types, I wished to avoid continuously traversing very long Switch() statement.

Therefore, to create an object, I call vFactoriesnEnumObjectTypeID via CGameObjectFactory::create() to call stored function that generates desired object.

The position of the appropriate function in the vFactories is identical to the nObjectTypeID, so I can use indexing to access the function.

So the question remains, how to proceed with garbage collection and avoid reported memory leaks?

#ifndef GAMEOBJECTFACTORY_H_UNIPIXELS
#define GAMEOBJECTFACTORY_H_UNIPIXELS

//#include "MemoryManager.h"
#include <vector>


template <typename BaseObject>
class CGameObjectFactory
{
public:
    // cleanup and release registered object data types
    bool ReleaseClassTypes()
    {
        unsigned int nRecordCount = vFactories.size();
        for (unsigned int nLoop = 0; nLoop < nRecordCount; nLoop++ )
        {
            // if the object exists in the container and is valid, then render it
            if( vFactories[nLoop] != NULL) 
                delete vFactories[nLoop]();
        }
        return true;
    }

    // register new object data type
    template <typename Object>
    bool RegisterClassType(unsigned int nObjectIDParam )
    {
        if(vFactories.size() < nObjectIDParam) vFactories.resize(nObjectIDParam);

        vFactories[nObjectIDParam] = &CreateObjectFunc<Object>;
        return true;
    }


    // create new object by calling the pointer to the appropriate type function
    BaseObject* create(unsigned int nObjectIDParam) const
    {
        return vFactories[nObjectIDParam]();
    }


    // resize the vector array containing pointers to function calls
    bool resize(unsigned int nSizeParam)
    {
        vFactories.resize(nSizeParam);
        return true;
    }

private:
    //DECLARE_HEAP;

    template <typename Object>
    static BaseObject * CreateObjectFunc()
    {
        return new Object();
    }


    typedef BaseObject*(*factory)();
    std::vector<factory> vFactories;
};


//DEFINE_HEAP_T(CGameObjectFactory, "Game Object Factory");

#endif // GAMEOBJECTFACTORY_H_UNIPIXELS
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

You can't clean up from inside the Factory class. It's the job of whatever code called create() to deallocate that memory later. The "cleanup" you've done just allocates and then destroys a new object of each type.

\$\endgroup\$
7
  • \$\begingroup\$ @DeadMG: + 1 for good answer and spending effort looking into my long question. Hi, DeadMG, I store all objects returned with *BaseObject create(unsigned int nObjectIDParam) const ** in separate vector elsewhere in my code. I clean those pointers. But I still get information about memory leaks on the mentioned line **return new Object(); **. Do you have an idea, please, if I should perform another cleaning? Can I delete pointers which I casted to different data types? \$\endgroup\$ Commented Mar 4, 2011 at 13:11
  • \$\begingroup\$ @Bunkai Satori: If you delete the pointers returned, then your tool is just wrong, and there's no two ways about it. The only way you could possibly improve it is by returning a smart pointer. \$\endgroup\$
    – DeadMG
    Commented Mar 4, 2011 at 14:10
  • \$\begingroup\$ @DeadMG: so you say, I should not delete the pointers returned by BaseObject* create(unsigned int nObjectIDParam) const and instead I should implement smart pointers? I tried std::smart_ptr, but I was having the same memory leak on the line return new Object(); \$\endgroup\$ Commented Mar 4, 2011 at 14:38
  • \$\begingroup\$ @Bunkai: You don't have any memory leak. It's your tool being wrong. You should use smart pointers wherever possible - but there's no memory leak in this segment of code if you delete the pointer returned by create correctly. \$\endgroup\$
    – DeadMG
    Commented Mar 4, 2011 at 17:52
  • \$\begingroup\$ It's worth bearing in mind that when a tool says a certain line is responsible for a memory leak, it doesn't mean that line is wrong. It means you're doing something wrong with the code that handles whatever is created by that line. \$\endgroup\$
    – Kylotan
    Commented Mar 4, 2011 at 19:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .