2012-02-10 6 views
2

私はMarmalade SDKの下で次のコードを実行しています。非常に奇妙なメモリリーク

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; 

}; 

注たびにテンプレートクラスが静的​​ローカル配列が作成され、1回目のために呼び出されdiscoverIdこと:私は私のコードやマーマレードで「バグ」があるかどうかを知る必要があります。

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

解放されていない:プログラムの終了時に

、マーマレードのメモリマネージャは、このラインで予約メモリがあることを訴えます。 (真実は私が配列を空にしないことです、しかし、どのように私は、私はその機能の外にアクセスする必要はありません!)。ここで

はキャッチです:マーマレードは非常に最初の呼び出し、この関数ので 予約専用メモリのために不平を言います!この関数は複数回呼び出され、いくつかの異なるテンプレートパラメータで呼び出されますが、最初の呼び出しで予約されたメモリに対してのみ不平が常に発生します。これは、この関数のさまざまな呼び出しの順序をミックスした場合でも同じです。最初のコールが自動的に解放された後のすべてのコールに予約されているメモリ - これをチェックしました。

今、誰が責任を負うのですか?

+1

std :: vector は、複数の要素のスペースをすぐに割り当てることができます。最初のプッシュが後続のすべてのプッシュにスペースを割り当てるヒットにならないことは確かです。 –

+0

@JoachimIsaksson私はstd :: vectorを使用します。非常に頻繁に、私は以前にこの問題を抱えていませんでした。それは "テンプレート+静的ローカル"の組み合わせと関係している必要があります –

答えて

1

私は "Marmalade"が何であるか分かりませんが(この単語のクイック検索には無関係の参照がたくさんあると思われます)、static FPIDArray siblingFunctionsに関してコードにリソースリークがありません。最初に関数が呼び出されたとき。 main()が終了した後、ある時点で破壊されます。静的なリンケージを持つオブジェクトの破壊の順序は、オブジェクトが構築される順序の逆ですが、これが関数の静的な静的な機能を拡張するかどうかはわかりません。

+0

ありがとう、私はそう思った。ママレードSDKのリンクは次のとおりです:http://www.madewithmarmalade.com/ –

+1

私はあなたが正しいと信じています。3.6.3/1は静的な記憶期間を持つ初期化されたオブジェクトに適用され、 "コンストラクタの完了またはスレッド記憶期間を持つオブジェクトの動的初期化は、 のものよりも前にシーケンスされ、別のもののデストラクターの完了は、最初のデストラクターの開始前にシーケンスされます。 –

関連する問題