文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

c++lambda捕获this导致多线程下类释放后还在使用的错误问题

2023-02-03 12:02

关注

Lambda介绍

“Lambda表达式是现代C++在C ++ 11和更高版本中的一个新的语法糖 ,在C++11、C++14、C++17和C++20中Lambda表达的内容还在不断更新。 lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常,lambda用于封装传递给算法或异步方法的几行代码 。

c++的lambda 可以捕获this指针,使lambda可以在自定义的function内使用类的成员函数,这是因为捕获this后隐式的在成员变量前加了this

但是需要注意的是,这里捕获this,不是以一种拷贝的方式,更像是一种引用(或者别名,描述可能不准确),当在外面这个类的生命周期结束时,lambda内部还在调用这个类的成员函数,那么就会出错

我遇到的问题是 捕获了类A的this,对A的一个shared_ptr进行操作。偶然会出现shared_ptr的内部基类spt_count_base的报错。看了下这个shared_ptr 的use_count和weak_count都是0,

这就非常奇怪。shared_ptr计数是线程安全的,(但是实际指向对象和计数不是原子操作),并且访问这个sptr也加了锁,为什么会出现被释放了的情况。

大概再说下情景

class A

{
  shared_ptr<B> sptr;

  sptr.func = [this](){ do something};

}
class B

{
  shared_ptr<map> sptrMap;

  func()

  {

      //概率崩溃
             sptrMap.erase();

  }
}

当A被析构后,B注册的回调被另一个线程调用了func();这时可能会出现A开始析构,刚好析构到B,并且B的sptrMap已经析构时,出现崩溃。但这个顺序不是确定的无法保证,所以也不一定必出现这种现象。

防止这种现象可以加个判断,在sptrMAp不为空时不进行析构。或者用weak_ptr.在捕获this前,用 weak_ptr p = std::shared_from_this;然后在lambda最开始用p.lock判断A是否释放

通过这个了解到了lambda捕获的一个坑,及类析构的顺序及析构时线程安全的保护

另附实际代码

using namespace std;
struct Foo {
  std::unique_ptr<int> p;
  std::function<void()> f() {
    p.reset(new int(1));
    return [=] { cout << *p << endl; };
  }
};

int main() {
  auto foo = new Foo();
  auto f = foo->f();
  delete foo;
  f();
}

运行结果为0而非1,而且这里输出0是未定义行为,因为访问的实际上是被回收的空间,只是因为编译器的delete并没有对回收的空间做额外的操作,所以p指向的仍然是原来那块,只不过那块已经被unique_ptr的析构函数自动清除了,只不过将清除的部分全部置为0而已。

到此这篇关于c++ lambda捕获this 导致多线程下类释放后还在使用的错误的文章就介绍到这了,更多相关c++ lambda捕获this内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯