"std::shared_ptr"循环依赖关系是如何导致问题的
How does `std::shared_ptr` cyclic dependency cause a problem
我发现了几个相关的问题,但我找不到关于"如何"发生这种情况的解释。
我有以下代码,它比可以创建循环shared_ptr
引用问题的版本落后一步。(返回前添加b.other = a;
导致问题(
为了更好地澄清,我在重要的行上添加了注释,以表明当时程序的状态。
#include <iostream>
#include <memory>
using namespace std;
struct Foo
{
explicit Foo(char i) : id{i} { cout << "Constructed " << id << endl; }
~Foo() { cout << "Destructed " << id << endl; }
shared_ptr<Foo> other = {};
char const id;
};
int main()
{
auto const a = make_shared<Foo>('a'); // a_use_count = 1, b_use_count = 0
auto const b = make_shared<Foo>('b'); // a_use_count = 1, b_use_count = 1
a->other = b; // a_use_count = 1, b_use_count = 2
return 0; // What happens now? Following is my "expectation" (which is wrong !)
// 1. destruct b => a_use_count = 1, b_use_count = 1
// 2. destruct a (in following order)
// 2.1 destruct a.other => b_use_count = 0 => show "Destructed b"
// 2.2 destruct a => a_use_count = 0 => show "Destructed a"
}
然而,事情并没有像我预期的那样发生。CCD_ 3和CCD_。我看到以下输出。
Constructed a
Constructed b
Destructed a
Destructed b
当程序返回到上面时,会发生什么?(我希望理解这一点将有助于理解循环依赖性问题(
析构函数主体在成员被销毁之前执行(构造函数行为的相反(
因此,当main
中的a
被销毁时,a
的共享指针计数首先达到零,然后调用托管Foo
的销毁器,首先生成消息Destructed a
,然后销毁other
,这导致Destructed b
被打印在其托管Foo
的销毁器中。
相关文章:
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 执行函数时导致崩溃的变量
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 使用 LuaBridge 将 LuaJIT 绑定到C++会导致"PANIC: unprotected error"
- C++/传递值导致#DEN
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- C++使用params创建线程函数会导致转换错误
- 为什么加载SDF会导致Mobilizer创建闭环错误
- Python中的for循环与C++有何不同
- 使用Vulkan hpp vk::enumerateInstanceVersion()会导致segfault
- 处理除以零会导致<csignal>意外行为
- 使用++运算符会导致意外的结果
- 换位表导致测试失败(但在游戏中运行良好)
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 为什么创建友元类的实例会导致"undefined reference to"错误?
- 是什么导致了Unity 3D中的"错误线程异常"?