【问题标题】:Although unique_ptr guaranteed to store nullptr after move, it still is pointing to the object?虽然 unique_ptr 保证在 move 后存储 nullptr,但它仍然指向对象?
【发布时间】:2016-03-04 11:55:24
【问题描述】:

我已经使用 GCC 5.2 (C++11) 测试了以下代码:

#include <iostream>
#include <memory>

struct Foo
{
    Foo()      { std::cout << "Foo::Foo\n";  }
    ~Foo()     { std::cout << "Foo::~Foo\n"; }
    void bar() { std::cout << "Foo::bar\n";  }
};

void f(const Foo &)
{
    std::cout << "f(const Foo&)\n";
}

int main()
{
    std::unique_ptr<Foo> p1(new Foo);  // p1 owns Foo
    if (p1) p1->bar();

    {
        //p1->bar();
        std::unique_ptr<Foo> p2(std::move(p1));  // now p2 owns Foo
        f(*p2);
        p1->bar();
        if(p1==nullptr)
        {
            std::cout<<"NULL"<<std::endl;
        }
        p1 = std::move(p2);  // ownership returns to p1
        std::unique_ptr<Foo> p3;
        p3->bar();
        std::cout << "destroying p2...\n";
    }

    if (p1) p1->bar();

    // Foo instance is destroyed when p1 goes out of scope
}

所以现在我的问题是,虽然 p1 在 move 操作后保证为 nullptr,但它似乎仍然指向前一个对象?

编辑: 是的,我在问为什么 p1->bar();仍然可以工作,因为 p1 已经移动,而 bar() 不是静态函数。 正如每个人都指出的那样,未定义的行为可能导致任何事情发生。 我现在已经遇到了足够多的未定义行为......如果有人能指出我在 C++11 中常见的未定义行为的集合,我将不胜感激。 提前致谢。

【问题讨论】:

  • 您的代码有未定义的行为。
  • 声明成员函数virtual,你会更好地改变它的崩溃。然后在附加了调试器的情况下运行你的应用程序并观察std::unique_ptr 的内部结构。
  • 你能简化一下,让你的实际问题更清楚吗?
  • 你在问为什么p1-&gt;bar();std::unique_ptr&lt;Foo&gt; p2(std::move(p1)); 之后起作用?
  • 您期待什么行为?在任何情况下,Foo::bar 总是做同样的事情。

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


【解决方案1】:

我假设你指的是这个:

std::unique_ptr<Foo> p2(std::move(p1));  // now p2 owns Foo
p1->bar();

它会输出“Foo::bar”吗?

那么,它应该做什么呢?您正在取消引用无效的指针。 Anything can happen.

在这种情况下,由于您没有访问不存在的 Foo 的任何成员,因此您很幸运在这里遇到了崩溃(因为在较低级别,没有实际的“物理”需要解除对0x0 的引用)。

但这并没有改变what you're doing is wrong的事实。

【讨论】:

    猜你喜欢
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 2015-11-21
    • 1970-01-01
    相关资源
    最近更新 更多