2

I am running the following piece of code under the Marmalade SDK. I need to know if there's a "bug" in my code or in Marmalade:

template <class Return = void, class Param = void*>
class IFunction {

private:

    static unsigned int counterId;

protected:

    unsigned int id;

public:

    //

    static unsigned int getNewId() { return counterId++; }

    template <class FunctionPointer>
    static unsigned int discoverId(FunctionPointer funcPtr) {

        typedef std::pair<FunctionPointer, unsigned int> FP_ID;
        typedef std::vector<FP_ID> FPIDArray;
        static FPIDArray siblingFunctions; // <- NOTE THIS

        typename FPIDArray::iterator it = siblingFunctions.begin();
        while (it != siblingFunctions.end()) {
            if (funcPtr == it->first) return it->second; /// found
            ++it;
        }

        /// not found
        unsigned int newId = getNewId();
        siblingFunctions.push_back( FP_ID(funcPtr, newId) ); // <- NOTE THIS

        return newId;
    }

    //

    virtual ~IFunction() {}

    bool operator<(const IFunction* _other) const {
        if (this->id < _other->id) return true;
        return false;
    }

    virtual Return call(Param) = 0;

};

Note that every time template class discoverId is called for the 1st time, a static local array is created.

At program exit, the Marmalade memory manager complains that the memory reserved at this line :

siblingFunctions.push_back( FP_ID(funcPtr, newId) );

hasn't been freed. (The truth is that I don't empty the array, but how could I, I don't have access to it outside that function!).

Here is the catch : Marmalade complains only for the memory reserved at the very first call of this function! This function is called several times and with several different template parameters, but the complaining always occurs only for the memory reserved at the 1st call. This is the case even if I mix up the order of the various calls to this function. Memory reserved for every call after the 1st one is automatically freed - I have checked this out.

So, who's to blame now?

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
Bill Kotsias
  • 3,258
  • 6
  • 33
  • 60
  • 1
    std::vector may allocate space for more than one element right away, you're sure it's not just the case that the first push takes the "hit" of allocating space for all your following pushes? – Joachim Isaksson Feb 10 '12 at 20:18
  • @JoachimIsaksson I use std::vector very often, I haven't had this problem before. It must have to do with the "template + static local" combination – Bill Kotsias Feb 10 '12 at 20:28

1 Answers1

1

I don't know what "Marmalade" is (and a quick search for this word expectedly found a lot of irrelevant references) but your code doesn't have a resource leak with respect to the static FPIDArray siblingFunctions: this object is constructed the first time the function is called. It is destroyed at some point after main() is exited. I seem to recall that the order of destruction of objects with static linkage is the reverse of order in which objects are constructed but I'm not sure if this extends function local statics.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • Thanks, I thought so. Well, here's the Marmalade SDK link : http://www.madewithmarmalade.com/ – Bill Kotsias Feb 10 '12 at 20:37
  • 1
    I believe you are correct about the order, 3.6.3/1 applies to initialized objects with static storage duration and says: "... If the completion of the constructor or dynamic initialization of an object with thread storage duration is sequenced before that of another, the completion of the destructor of the second is sequenced before the initiation of the destructor of the first." – Richard Corden Feb 10 '12 at 21:11