使用unique_ptr和shared_ptr进行奇怪的段错误

时间:2012-05-10 11:03:19

标签: c++ c++11 shared-ptr unique-ptr

我遇到了一个奇怪的段错误。原因实际上导致了我的错误,但我仍然不明白为什么在这里引起分段错误......代码是:

#include <memory>
int main(int argc, char **arv)
{
    int *i = new int;
    std::unique_ptr<int> u1(i);
    std::unique_ptr<int> u2;
    u1 = std::move(u2); // line 7
    std::shared_ptr<int> s1(i); // line 8
    std::shared_ptr<int> s2;
    s2 = s1;
}

我使用g ++ 4.6和-std=c++0x编译并获得段错误。

如果我将第7行更改为u2 = std::move(u1);(这是错误),它就会消失。 如果我将第8行更改为std::shared_ptr<int> s1(new int(3));(当然我不想要),它也会消失。如果我从第8行删除也没有段错误。

所以没有伤害,但我不明白为什么会出现段错误。据我了解,
在第7行中,一个空指针被分配给u1。没有重置(),没有范围的结束。然而i似乎无效。是有意的吗?这意味着在移动指针时必须非常小心,因为另一个对象可能会被破坏!

你怎么看?我如何保护自己免受这种伤害?

谢谢,Steffen

2 个答案:

答案 0 :(得分:10)

您的第8行错误:在i中捕获unique_ptr后,您不能再将其提供给某些其他所有权对象!每位所有者都会尝试删除*i,这是错误的。

相反,您应该从唯一指针创建共享指针:

std::shared_ptr<int> s1(std::move(u2));

(另外,你有u1u2错误的方法。)

答案 1 :(得分:3)

这一行:

u1 = std::move(u2);

删除u1存储的前一个指针。因此,您的i指针将被释放。创建一个持有free'd指针的shared_ptr是未定义的行为。