1

I've tested following code with 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
}

So now my question is, although p1 is guaranteed to be nullptr after move operation, it seemed still is pointing to the previous object?

Edit: Yes, I'm asking why p1->bar(); still work given p1 already moved while bar() is not static function. As everybody pointed out, undefined behavior can cause anything to happen. I've been running into enough undefined behavior nowadays... I would appreciate if somebody can point me to a collection of common undefined behaviors in C++11. Thanks in advance.

Jokies
  • 11
  • 2

1 Answers1

6

I assume you are referring to this:

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

and that it outputs "Foo::bar"?

Well, what should it do instead? You are dereferencing an invalid pointer. Anything can happen.

In this case, since you're not accessing any members of the non-existent Foo, you'd be bloomin' lucky to get a crash here (because, at a lower-level, no actual "physical" dereferencing of 0x0 need occur).

But it doesn't change the fact that what you're doing is wrong.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055