取消引用右值 shared_ptr

Dereference a rvalue shared_ptr

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

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

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

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

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

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

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

声明

auto & v1 = *foo(params);

是潜在的未定义行为

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

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

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

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