【问题标题】:Dereference a rvalue shared_ptr取消引用右值 shared_ptr
【发布时间】:2019-06-26 09:48:58
【问题描述】:

我正在使用一个导出函数的库,例如:

// there is some type T
std::shared_ptr<T> foo(params);

虽然下面的代码可以正常工作:

auto p = foo(params);
auto & v0 = *p;
// use v0 as a T's reference

以下崩溃:

auto & v1 = *foo(params);
// use v1 as a T's reference

那么v0v1 有什么区别?非常感谢您的帮助。

【问题讨论】:

    标签: c++ shared-ptr rvalue


    【解决方案1】:

    shared_ptr 指向的对象只有在至少有 一个 共享指针仍然指向它时才存在。

    在您的示例中,可能只有一个这样的指针,它由foo 返回。

    对于v0p 成为保持对象存活的shared_ptr

    对于v1,只有一个临时共享指针仅在v1 的初始化期间存在。当你使用引用时,被指向的指针和对象已经消失,在使用时它是一个悬空的。

    【讨论】:

    • 非常感谢,简短而准确的回答。我认为取消引用可能有助于从共享指针实例中“固定”T 的对象,但事实并非如此。
    • @TaThanhDinh - 不,指针固定对象,而不是相反。对对象的引用仍然是“愚蠢”的引用。
    【解决方案2】:

    声明

    auto & v1 = *foo(params);
    

    是一种潜在的未定义行为

    函数foo 可能在内部构造了一个std::shared_ptr 并将其作为一个临时对象(技术上是一个prvalue)返回给调用者,该对象应该被分配给某个变量。

    您不会将表达式的智能指针分配给任何变量。但是,您抓取指向的对象(使用 * 运算符)并将其分配给引用 v1

    在表达式评估结束时,临时的std::shared_ptr 将被销毁,并且(作为智能指针)指向的对象也将被销毁。

    因此,auto &amp; v1 指的是一个被破坏的对象,访问它是一种未定义的行为(在大多数情况下会产生分段错误)。

    【讨论】:

    • 感谢您指出访问被破坏的对象是一种未定义的行为。
    【解决方案3】:

    在您的第一个示例中,p 保留在范围内,持有对该对象的引用,从而使其保持活动状态。在您的第二个示例中,shared_ptr 在创建 v1 之后被销毁,这会销毁对象(假设它是唯一的引用)并留下 v1 指向未分配的内存。

    【讨论】:

      猜你喜欢
      • 2017-05-02
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 2017-06-18
      • 2013-09-17
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      相关资源
      最近更新 更多