Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从std::map中删除std::function lambda包装方法_C++_C++11_Memory Leaks_Lambda_Std Function - Fatal编程技术网

C++ 从std::map中删除std::function lambda包装方法

C++ 从std::map中删除std::function lambda包装方法,c++,c++11,memory-leaks,lambda,std-function,C++,C++11,Memory Leaks,Lambda,Std Function,我正在使用std::function和std::maps创建一个回调系统。映射使用ints作为键,值为std::function。我将方法绑定到这些函数中。我想知道我是否调用map.erase(I),这会从内存中删除std::函数,还是会导致内存泄漏 下面是一些示例代码: #include <iostream> #include <functional> #include <map> using namespace std; class TestClass

我正在使用
std::function
std::map
s创建一个回调系统。映射使用
int
s作为键,值为
std::function
。我将方法绑定到这些函数中。我想知道我是否调用map.erase(I),这会从内存中删除std::函数,还是会导致内存泄漏

下面是一些示例代码:

#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
  };                   
#包括
#包括
#包括
使用名称空间std;
类TestClass{
公众:
TestClass(int\u i、map和test\u map):i(\u i){
test_map[i]=[&](){this->lambda_test();};
};

void lambda_test(){cout关于lambdas的实际内存分配,这里有一个非常好的解释:


据我所知,lambda语法创建一个r值,并将其复制(连同任何捕获的状态等)到std::函数中。这将由std::函数的析构函数删除,在调用erase(和/或映射超出范围)时由std::map的析构函数调用.

虽然这不是好代码,但没有内存泄漏;您正在通过值(而不是指针)将
std::function
s存储在
std::map
中,因此
std::map::erase
将调用
std::function
的析构函数


换句话说,你没有
new
ing任何
std::function
,所以你不需要
delete
any
std::function

是什么让它不是好代码?我应该在映射中存储std::function指针而不是实际对象吗?出于好奇,这段代码特别是什么“不好”?@MaxTyler为什么
newtestclass
?TestClass
到底在做什么?我知道这是一个玩具示例,但如果您在实际代码中使用类似于此模式的任何东西,那么我高度怀疑设计缺陷。@sji我可以提出一些批评,比如生命周期管理得不太安全。它捕获
&
并获取
e> ,它很幸运地忽略了通过
&
捕获的请求:使用
[&]
在一个持续时间超过当前上下文的lambda中,代码气味非常脆弱。这并不难继续?@MaxTyler请注意CodeReview问题与SO问题不同;请务必阅读指南!在这段代码中唯一要注意的是
删除测试;
测试地图。擦除(1) 
lambda引用悬挂的
指针。在本例中,这并不有害,但“成长”应用程序或多线程应用程序可能会开始显示未定义的行为。通常,代码中存在一个奇怪的生命周期问题,可以通过在映射中而不是lambda中存储TestClass来解决。