c++ - `std::shared_ptr`循环依赖如何导致问题

标签 c++ c++11 memory-management smart-pointers

我发现了几个相关的问题,但我找不到关于这种情况“如何”发生的解释。

我有以下代码,它比可能创建循环 shared_ptr 引用问题的版本落后一步。 (在 return 之前添加 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"
}

然而,事情并没有按照我的预期发生。 ab 以相反的顺序被破坏。我看到以下输出。

Constructed a
Constructed b
Destructed a
Destructed b

当程序返回上面时到底发生了什么? (我希望理解这一点有助于理解循环依赖问题)

最佳答案

析构函数主体在成员被销毁之前执行(与构造函数行为相反。)

因此,当main中的a被析构时,a的共享指针计数首先达到零,然后托管 Foo 的析构函数被调用,首先打印消息 Destructed a,然后然后 其他 被销毁,这会导致 Destructed b 在其托管 Foo 的析构函数中打印。

关于c++ - `std::shared_ptr`循环依赖如何导致问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58675139/

相关文章:

c++ - 在类模板(链接列表)中重载运算符

c++ - 匿名空无标记类、结构、 union 和枚举

c++ - 即使传入也无法确定模板类型

c - 指定驻留在特定地址的类型

c++ - 使已删除的指针无效?

c++ - HIP-Clang 内联装配

c++ - 颠倒排序顺序

c++ - C++0x forward_list在不同场景下的表现如何?

c++ - 将任意 lambda 表达式传递给函数?

c++ - 使用 sbrk 自定义内存管理