2016-08-22 47 views
4

我使用std::functionstd::map s創建了一個回調系統。該地圖使用int s作爲關鍵字,值爲std::function。我將方法綁定到這些函數中。我想知道如果我打電話給map.erase(i),是否會從內存中刪除std :: function,還是會出現內存泄漏?從std :: map中刪除std :: function lambda-wrapped方法

下面是一些示例代碼:

#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)'之間,lambda引用一個懸掛的''''''指針。在這個例子中,這並不是有害的,但'成長中'的應用程序或多線程應用程序可能會開始顯示未定義的行爲。通常,代碼中存在一個奇怪的生命期問題,可以通過在地圖中存儲TestClass而不是lambda來解決。 – stefaanv

回答

3

雖然這不是好的代碼,但沒有內存泄漏;您按值(而不是指針)存儲std::function s,因此std::map::erase將調用std::function的析構函數。換句話說,你不是new ing std::function,所以你不需要delete任何std::function

+0

是什麼讓它不好?我應該存儲std :: function指針而不是地圖中的實際對象嗎? –

+0

出於好奇,這個代碼的特別之處是「不好」? – sji

+0

@MaxTyler爲什麼'new TestClass'?什麼是TestClass?在這裏做什麼?我明白這是一個玩具的例子,但如果你在實際的代碼中使用了這種模式,那麼我高度懷疑設計缺陷。 – Daniel

1

有什麼實際的內存分配這裏的條件與lambda表達式的推移很好的解釋:

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

據我瞭解,在lambda語法創建的r值,複製(以及任何捕獲的狀態等)到std ::函數中。當你調用erase(和/或當地圖超出範圍時),std :: map的析構函數會調用std :: function的析構函數,這將被刪除。