gpt4 book ai didi

c++ - global static const shared_ptr 奇怪地被另一个 shared_ptr 的析构函数窃取和删除,为什么?

转载 作者:太空宇宙 更新时间:2023-11-04 11:44:33 25 4
gpt4 key购买 nike

我正在编写一个文件管理器,当我打开一个文件夹两次时看到可重现的崩溃。最小化相关代码:

#include <vector>
#include <memory>
#include <boost/smart_ptr.hpp>

namespace myns {
using std::shared_ptr;
}

class Base {
public:
virtual ~Base() {}
};

class Derived_1 : public Base {
public:
~Derived_1() {} // breakpoint 1
};

myns::shared_ptr<Derived_1> Derived_1_ptr() {
static const myns::shared_ptr<Derived_1> r{new Derived_1};
return r;
}

class Derived_2 : public Base {};
myns::shared_ptr<Derived_2> Derived_2_ptr() {
static const myns::shared_ptr<Derived_2> r{new Derived_2};
return r;
}
std::vector<myns::shared_ptr<Base>> all_derived_ptrs() {
return{Derived_1_ptr(), Derived_2_ptr()}; // no breakpoint
}

void test_1() {
all_derived_ptrs(); // breakpoint 2
all_derived_ptrs(); // breakpoint 3
}

void test_2() {
{
std::vector<myns::shared_ptr<Base>> t{Derived_1_ptr(), Derived_2_ptr()};
}
{
std::vector<myns::shared_ptr<Base>> t{Derived_1_ptr(), Derived_2_ptr()};
}
}

int main() {
test_1();
return 0;
}

Derived_1_ptr() 和 Derived_2_ptr() 实际上是解决 initialization order problem 问题的全局变量。 .

使用这些代码:

  1. 在 Visual Studio 2013 中编译并运行而不调试,崩溃(Win8:程序停止工作)。
  2. 将 main 更改为 test_2(),再次崩溃。
  3. 改回test_1,同上设置3个断点,调试。它首先在#2 处中断,然后是#1,然后是#3,然后弹出一个对话框说“已触发断点”,它在 ntdll 中中断,而“下一条语句”位于 no breakpoint。 .
  4. 再次切换到 test_2,在第一个 t 之后设置一个断点构建好了,看t在调试窗口中。 t[0]有 1 个强引用和 t[1]有 2 个强引用。

所以我可以推断,当构建第一个 vector 时,Derived_2_ptr()被正确复制 (++reference_count),而 Derived_1_ptr()似乎是从 static const r(reference_count 仍然是 1)中被窃取( move ?)。当第一个 vector 被销毁时Derived_2_ptr()正确执行 --reference_count 并且还活着,但是 Derived_1_ptr()在创建第二个 vector (它是一个全局静态变量!)之前失去它唯一的引用并死亡。

为什么? 可以将 move 构造函数应用于static const东西?

我尝试更改 Derived_x_ptr() 的返回类型至 const myns::shared_ptr<Derived_x>&myns::shared_ptr<Base> , 两者都正常工作。

此外,如果我删除 Derived_2_ptr() 并使 all_derived_ptrs return{Derived_1_ptr(), nullptr} , Derived_1_ptr() 神奇地起作用了。

如果我改用 boost::shared_ptr,问题就隐藏起来了(没有程序停止对话框)但是 ~Derived_1() 仍然被过早调用。

这是怎么回事?标准是否允许这种 move ?它是特定于 Microsoft 的东西,还是特定于 VS2013 的东西(我没有另一个 C++11 编译器)?有什么想法吗?

最佳答案

关于c++ - global static const shared_ptr 奇怪地被另一个 shared_ptr 的析构函数窃取和删除,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20195999/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com