lots_of_questions
lots_of_questions

Reputation: 1149

C++ nullptr detection

I have the following code. I don't understand why the first conditional gets invoked in B.GetNum(). How can I ensure when a gets deleted in main that my class B does not try to use the deleted variable?

class A
{
public:
    A(int num) : m_num(num) {}
    int GetNum() { return m_num; }

private:
    int m_num;
};

class B
{
public:
    B(A* a_) : a(a_) {}
    int GetNum()
    {
        if (a != nullptr)
        {
            return a->GetNum(); // Why does this branch get called?
        }
        else
        {
            return -1;
        }
    }

private:
    A* a;
};

int _tmain(int argc, _TCHAR* argv[])
{
    A* a = new A(5);
    B b = B(a);
    delete a;
    a = nullptr;

    int result = b.GetNum();

    return 0;
}

Upvotes: 1

Views: 81

Answers (3)

ISanych
ISanych

Reputation: 22710

Because you copied A* value into you class - it is never changed, but when you deleted original allocated value, you pointer point to a garbage location.

Upvotes: 1

NathanOliver
NathanOliver

Reputation: 181067

The problem you are having is you copy the pointer when you create b in main(). When you change a in main() it has no effect on pointer stored in b.

This is a perfect use case for a std::weak_ptr. You can have B take a weak_ptr and then in GetNum you can check if the pointer still exist.

Upvotes: 6

Bo Persson
Bo Persson

Reputation: 92381

You have two different a. The statement a = nullptr; affects only the pointer inside main. The pointer inside b is a copy and contains the old value (now invalid).

Using it in GetNum() leads to undefined behavior, and anything can happen.

Upvotes: 1

Related Questions