【问题标题】:Making shared_ptr from the raw pointer of another shared_ptr从另一个 shared_ptr 的原始指针生成 shared_ptr
【发布时间】:2020-07-17 18:08:52
【问题描述】:

说,我有一个shared_ptr<A> ptrFirst,它已初始化并指向内存中的某个对象。现在,我像这样定义一个新的shared_ptr

shared_ptr<A> ptrSecond = make_shared<A>(ptrFirst.get());

我知道我可以使用简单的分配来防止出现任何问题。但是我想知道如果我这样定义ptrSecond,我会为同一个对象有两个不同的控制块吗?这还很糟糕吗?

【问题讨论】:

  • 在析构函数中设置断点。 TLDR:这很糟糕。
  • 这里还有另一个案例,实际的minimal reproducible example 会有很大帮助,因为它会发现其他人指出的问题。反过来,这将导致要么不需要问这个问题,要么问一个更好的问题。

标签: c++ smart-pointers


【解决方案1】:

除非您有一个将A* 作为唯一参数的构造函数,否则您的行不会编译事件。

如果您确实有构造函数A::A(A*),那么make_shared 将创建一个新对象 - 这很好。

如果您改用std::shared_ptr 构造函数:

std::shared_ptr<A> ptrSecond = std::shared_ptr<A>(ptrFirst.get());

那就有问题了。这将导致双重释放,即UB。

【讨论】:

    【解决方案2】:

    但我想知道如果我这样定义ptrSecond,我会为同一个对象有两个不同的控制块吗?

    没有。这段代码:

    shared_ptr<A> ptrSecond = make_shared<A>(ptrFirst.get());
    

    逻辑上等于:

    shared_ptr<A> ptrSecond( new A( ptrFirst.get() ) );
    

    所以基本上它将创建A 的新实例并使用指向另一个A 的指针对其进行初始化,当然只有在您定义了正确的ctor 时它才会编译。

    这还很糟糕吗?

    如果你的意思是这样的:

        shared_ptr<A> ptrSecond( ptrFirst.get() );
    

    是的,这很糟糕,因为它会由于双重释放而导致 UB。

    【讨论】:

    • 更糟糕的是,如果您在第一个指针被销毁后尝试使用第二个指针,您也会得到 UB。
    猜你喜欢
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2019-09-29
    • 2012-09-07
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多