2012-02-10 4 views
2

Я запускаю следующий фрагмент кода под SDK Marmalade. Мне нужно знать, если есть «ошибка» в моем коде или в 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; 

}; 

Обратите внимание, что каждый раз, когда шаблон класса discoverId вызывается для 1-й раз, статический локальный массив создается.

При выходе из программы, диспетчер памяти Мармелад жалуется, что память, зарезервированная на этой линии:

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

не был освобожден. (Правда в том, что я не освобождаю массив, , но как я мог, у меня нет доступа к нему вне этой функции!).

Вот улов: Мармелад жалуется только на память зарезервирован при первом вызове этой функции! Эта функция вызывается несколько раз и с несколькими различными параметрами шаблона, но жалоба всегда происходит только для памяти, зарезервированной при первом вызове. Это так, даже если я смешиваю порядок различных вызовов этой функции. Память, зарезервированная для каждого вызова после 1-го, автоматически освобождается - я проверил это.

Итак, кто виноват сейчас?

+1

std :: vector может выделить пространство для более чем одного элемента сразу, вы уверены, что это не тот случай, когда первый толчок занимает «хит» выделения пространства для всех ваших последующих нажатий? –

+0

@JoachimIsaksson Я использую std :: vector очень часто, у меня не было этой проблемы раньше. Это должно быть связано с комбинацией «шаблон + статический локальный» –

ответ

1

Я не знаю, что такое «Мармелад» (и быстрый поиск этого слова ожидал найти много нерелевантных ссылок), но ваш код не имеет утечки ресурса относительно static FPIDArray siblingFunctions: этот объект построен при первом вызове функции. Он разрушается в какой-то момент после выхода main(). Кажется, я помню, что порядок уничтожения объектов со статической связью - это обратный порядок, в котором объекты строятся, но я не уверен, что это расширяет функцию локальной статики.

+0

Спасибо, я так и думал. Ну, вот ссылка SDK Marmalade: http://www.madewithmarmalade.com/ –

+1

Я считаю, что вы правильно относитесь к заказу, 3.6.3/1 относится к инициализированным объектам со статической продолжительностью хранения и говорит: «... Если завершение конструктора или динамическая инициализация объекта с длительностью хранения потока секвентируется до того, как у другой, завершение деструктора второго секвенируется перед инициацией деструктора первого ». –