2016-08-22 97 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的析构函数,这将被删除。