当前位置: 首页 > news >正文

【问题解决】C++调用shared_from_this()报错bad_weak_ptr解决方案

【问题解决】C++调用shared_from_this()报错bad_weak_ptr解决方案

一、问题背景

在 C++11 之前,通常使用 std::shared_ptr 来管理对象的生命周期,但如果一个对象需要在内部获取指向自身的 shared_ptr,就比较麻烦。直接构造一个 shared_ptr 会导致引用计数不正确,从而引发内存泄漏或悬空指针的问题。

因此,C++11 引入了 std::enable_shared_from_this,它提供了一种安全且高效的方式,让一个对象能够在内部获取指向自身的 shared_ptr

通过继承 std::enable_shared_from_this,类可以调用 shared_from_this() 函数来获取指向自身的 shared_ptr。这个函数会保证 shared_ptr 的引用计数是正确的,避免了手动管理引用计数的复杂性。

二、正常情况

正常情况下,在Test函数中使用shared_from_this();,编译执行成功,可以捕获符合生命周期的this指针。

#include <memory>class Node : public std::enable_shared_from_this<Node> {
public:Node() {}~Node() {}void Test() {auto sharedThis = shared_from_this();}
};int main() {std::shared_ptr<Node> node1 = std::make_shared<Node>();node1->Test();return 0;
}

三、异常情况

  1. 构造函数中调用shared_from_this()
#include <memory>class Node : public std::enable_shared_from_this<Node> {
public:Node() {auto sharedThis = shared_from_this();}~Node() {}void Test() {}
};int main() {std::shared_ptr<Node> node1 = std::make_shared<Node>();node1->Test();return 0;
}
  1. unique_ptr构造enable_shared_from_this对象
#include <memory>class Node : public std::enable_shared_from_this<Node> {
public:Node() {}~Node() {}void Test() {auto sharedThis = shared_from_this();}
};int main() {std::unique_ptr<Node> node1 = std::make_unique<Node>();node1->Test();return 0;
}
  1. 裸指针构造enable_shared_from_this对象
#include <memory>class Node : public std::enable_shared_from_this<Node> {
public:Node() {}~Node() {}void Test() {auto sharedThis = shared_from_this();}
};int main() {Node* node1 = new Node();node1->Test();return 0;
}

以上三种情况都能编译成功,但执行时报错:

terminate called after throwing an instance of 'std::bad_weak_ptr'what():  bad_weak_ptr
Aborted (core dumped)

四、异常分析

  1. 查看c++ reference中std::bad_weak_ptr的描述:当shared_ptr指向一个已经被删除的对象时会抛出std::bad_weak_ptr异常。

    std::bad_weak_ptr is the type of the object thrown as exceptions by the constructors of std::shared_ptr that take std::shared_ptr as the argument, when the std::shared_ptr refers to an already deleted object.

  2. 查看shared_ptr.h头文件中的shared_from_this()源码和_M_weak_this定义。

public:shared_ptr<_Tp>shared_from_this(){ return shared_ptr<_Tp>(this->_M_weak_this); }shared_ptr<const _Tp>shared_from_this() const{ return shared_ptr<const _Tp>(this->_M_weak_this); }
mutable weak_ptr<_Tp>  _M_weak_this;
  1. 发现shared_from_this()实现就是将一个weak_ptr的this指针转换成shared_ptr指针的过程。

  2. 构造函数中调用shared_from_this()时,Node实例还未被构造,_M_weak_this还未生成,所以报错bad_weak_ptr

  3. unique_ptr构造enable_shared_from_this对象和裸指针构造enable_shared_from_this对象都不被std::shared_ptr管理,当调用shared_from_this()时,将导致未定义行为。

五、解决方案

  1. 对于构造函数中调用shared_from_this()的情况,应该避免在构造函数中调用shared_from_this(),解决办法即将相关逻辑移到函数中执行,在构造完成后调用相应函数以实现相同逻辑。
  2. 对于非unique_ptr构造enable_shared_from_this对象和裸指针构造enable_shared_from_this对象的情况,应使用std::make_sharedstd::shared_ptr实现相关函数的构造,使构造出的对象受std::shared_ptr管理。

六、参考文档

  1. C++ reference之std::bad_weak_ptr:https://en.cppreference.com/w/cpp/memory/bad_weak_ptr。
  2. C++源码之shared_ptr.h头文件。

http://www.mrgr.cn/news/56554.html

相关文章:

  • 【分布式技术】中间件-zookeeper安装配置
  • nginx子目录部署访问并且刷新不报404
  • JMeter详细介绍和相关概念
  • 2.2机器学习--逻辑回归(分类)
  • 天锐绿盾 vs Ping32:企业级加密软件大比拼
  • 在分类内用最大最小值筛选(每个分类找出一个)
  • 《吉林大学学报(理学版)》
  • 增量编码器和绝对编码器的原理介绍
  • 解决Eclipse中’Run As’菜单缺少’Run on Server’选项的问题
  • MySQL9.0安装教程zip手动安装(Windows)
  • 嵌入式大厂物联网(IoT)高频面试题及参考答案
  • 逐行讲解transformers中model.generate()源码
  • 每天五分钟深度学习:逻辑回归和神经网络
  • MyBatis-Plus 代码生成器
  • java--多态(详解)
  • 00 DSA-- 入门、实现动态数组
  • 阅读笔记 Contemporary strategy analysis Chapter 13
  • 算法题总结(二十)——并查集
  • stm32精密控制步进电机(基础篇)
  • 思想是花 嘴是大地
  • 考研篇——数据结构王道3.2.2_队列的顺序实现
  • linux—基础命令及相关知识
  • 对比学习论文随笔 1:正负样本对(Contrastive Learning 基础论文篇)
  • 基于单片机的磁耦合谐振式无线电能传输系统设计
  • 【R + Python】iNaturalist 网站图片下载 inat api
  • MySQL 中 LIKE 模糊查询如何优化?