如果我使用unique_ptr的原始指针然后使用reset,原始指针仍然保证有效吗?

wrh*_*all 5 c++ unique-ptr

我很确定这是有效的.

int foo = 51;
int* bar = &foo;
foo = 3;
Run Code Online (Sandbox Code Playgroud)

所以酒吧仍然有效,并且*bar == 3.

如果我们说,怎么样?

std::unique_ptr<int> foo(new int(51));  // should probably use make_unique
int* bar = foo.get();
foo.reset(new int(3));
Run Code Online (Sandbox Code Playgroud)

我有保证*bar == 3吗?或者我通过继续引用bar导致未定义的行为?

vso*_*tco 9

一点都不.您将获得未定义的行为,因为由其管理的原始指针unique_ptr由reset.实际上,unique_ptr删除托管指针并重新分配一个新指针,因此旧指针将继续指向旧地址,该地址不再有效.您的代码等同于:

#include <iostream>

int main()
{
    int* managed = new int(51); // equivalent to unique_ptr(new int(51));
    int* bar = managed; // equivalent of unique_ptr::get
    delete managed; managed = new int(3); // equivalent to unique_ptr::reset(new int(3))
    std::cout << *bar << std::endl; // Wrong!!! Undefined behaviour, bar is dangling!
}
Run Code Online (Sandbox Code Playgroud)

你的第一个代码片段确实是正确的,因为你没有更改那里的任何地址,你只是更改指针指向的变量,所以当然取消引用指针会得到更新的值.


Bri*_*ian 8

不,如果你重置一个unique_ptr,它将删除它拥有的指针.

你可以做:

int* bar = foo.release();
Run Code Online (Sandbox Code Playgroud)

这会导致foo放弃其指针的所有权并将其返回.

  • 是的,这就是`release()`的作用.是的,如果你首先得到指针然后指向`release()`指针,你的指针仍然有效(前提是`unique_ptr`在`release()`之前没有改变). (2认同)