取消引用右值shared_ptr

时间:2019-06-26 09:48:58

标签: c++ shared-ptr rvalue

我正在使用一个库,该库可以导出如下功能:

// 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有什么区别?非常感谢您的帮助。

3 个答案:

答案 0 :(得分:9)

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

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

对于v0p成为shared_ptr,使对象保持活动状态。

对于v1,只有一个临时共享指针仅在v1初始化期间存在。在您使用引用时,指向的指针和对象已消失,在使用时使其成为悬垂的指针。

答案 1 :(得分:3)

声明

auto & v1 = *foo(params);

是潜在的未定义行为

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

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

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

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

答案 2 :(得分:1)

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