3

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

#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。没有reset(),没有范围的结束。尽管如此i,从那里开始似乎是无效的。这是故意的吗?这意味着在移动指针时必须非常小心,因为可能会破坏另一个对象!

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

谢谢,史蒂芬

4

2 回答 2

11

你的第 8 行是错误的:一旦你i在 中捕获unique_ptr,你就不能再把它交给其他一些拥有所有权的对象!每个所有者都会尝试删除*i,这是错误的。

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

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

(另外,你有u1错误u2的方式。)

于 2012-05-10T11:13:23.563 回答
4

这一行:

u1 = std::move(u2);

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

于 2012-05-10T11:13:21.740 回答