std::weak_ptr 与 std::make_shared 的分配

std::weak_ptr assignment with std::make_shared

我在使用 std::weak_ptrstd::make_shared 时偶然发现了这种行为,我发现它有点奇怪。我正在使用 C++11。

#include <iostream>
#include <memory>

int main()
{
  std::weak_ptr<int> weak;

  std::shared_ptr<int> shared {std::make_shared<int>(42)};
  weak = shared;
  std::cout << "Meaning of life: " << *weak.lock() << std::endl;

  weak = std::make_shared<int>(23);
  std::cout << "Meaning of life: " << *weak.lock() << std::endl;

  return 0;
}

第一个 std::cout 打印正常,第二个给我一个段错误。我试着在 cppreference 上查看 std::weak_ptrstd::shared_ptr 的页面,但我仍然不明白为什么会这样。必须创建一个临时对象对我来说感觉很麻烦,这是 C++14 中已经解决的问题还是我没有看到的问题?

谢谢!

如果 shared_ptr 对象仍然存在且指向同一底层对象,则 weak_ptr 只能在锁定后取消引用。

在你的第一部分

std::shared_ptr<int> shared {std::make_shared<int>(42)};
weak = shared;
std::cout << "Meaning of life: " << *weak.lock() << std::endl;

确实是这样。第二部分

weak = std::make_shared<int>(23);
std::cout << "Meaning of life: " << *weak.lock() << std::endl;

事实并非如此,因为 shared_ptr 是一个临时对象。

您在这里遇到的正是 weak_ptr 的构建目的 - 只有当其他 shared_ptr 指向相同的基础对象时它才有效。即its purpose:

std::weak_ptr is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by std::shared_ptr... If the original std::shared_ptr is destroyed at this time, the object's lifetime is extended until the temporary std::shared_ptr is destroyed as well.

这是因为您在以下行中创建了一个临时共享指针并立即将其分配给一个弱指针:

weak = std::make_shared<int>(23);

赋值运算符结束后,临时共享指针被销毁,引用计数变为0(因为弱指针不增加引用计数器),因此堆上的资源被删除。