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