2016-08-22 6 views
4

std::functionstd::mapを使用してコールバックシステムを作成しています。マップはintをキーとして使用し、値はstd::functionです。私はそれらの関数にメソッドを束縛します。 map.erase(i)と呼ぶと、メモリからstd :: functionを削除するのだろうか?それともメモリリークがありますか?ここでstd :: functionラムダラップされたメソッドをstd :: mapから削除する

は、いくつかのサンプルコードです:

#include <iostream> 
#include <functional> 
#include <map> 

using namespace std; 

class TestClass{ 
    public: 
     TestClass(int _i, map<int, function<void()>>& test_map):i(_i){ 
      test_map[i]=[&](){this->lambda_test();}; 
     }; 
     void lambda_test(){cout << "output" << " " << i<< endl;}; 
    private: 
     int i; 
}; 

int main() { 
    map<int, function<void()>> test_map; 
    TestClass* test = new TestClass(1, test_map); 
    test_map[1](); 
    delete test; 
    test_map.erase(1); // <-- here 
    };     

最後test_map.erase(1);がメモリからstd::functionを削除していますか?

+0

このコードで唯一注意すべきことは、 'delete test;'と 'test_map.erase(1);'の間にあります。ここでは、ラムダがぶら下がっている 'this'ポインタを参照しています。この例では、これは有害ではありませんが、「成長中の」アプリケーションまたはマルチスレッドのアプリケーションでは未定義の動作が開始される可能性があります。一般的に、ラムダの代わりにマップにTestClassを格納することで解決できる、コード内に奇妙な生涯の問題があります。 – stefaanv

答えて

3

これは良いコードではありませんが、メモリリークはありません。 (ポインタではなく)std::functionstd::mapに格納しているので、std::map::eraseはデストラクタをstd::functionと呼びます。

別の言い方をすれば、あなたはどのstd::functiondeleteする必要はありませんので、あなたは、任意のstd::functionをINGのnewじゃありません。

+0

それは良いコードではありません?実際のオブジェクトではなく、std :: functionポインタをマップに格納する必要がありますか? –

+0

好奇心を要して、特にこのコードについては、「うまくいかない」ものは何ですか? – sji

+0

@MaxTylerなぜ 'new TestClass'ですか? 'TestClass'はここで何をしていますか?私はこれがおもちゃの例だと理解していますが、あなたが実際のコードでこのパターンのようなものを使用しているなら、私は設計の欠陥を疑います。 – Daniel

1

ここでは、実際のメモリ割り当ての面でラムダで何が起こっの非常に良い説明があります:

https://stackoverflow.com/a/12203426/1230538

私の理解では、ラムダ構文は、コピー、r値を作成します(キャプチャされた状態など)をstd :: functionに追加します。これはstd ::関数のデストラクタによって削除されます。std :: mapの消去は、消去を呼び出したとき(および/またはマップが有効範囲外になったとき)に呼び出されます。

関連する問題