Paler
Paler

Reputation: 349

C++ operators '&' and '*' with invalid pointer

In C++, we can use '*' to get the value of a pointer and '&' to get the address (pointer) of a value. But I met something confusing when using these operators on an invalid pointer.

Here are my test codes:

#include <iostream>

using namespace std;

class B
{
public:
    B() { x = 10; }
    int x;
    int GetX() { return x; }
};

class A
{
public:
    B* b;
    A()
    {
        b = nullptr;
    }
    B* GetB() { return b; }
};

int main()
{
    A * a = new A();

    B ib = *a->GetB();
    B * pb = &ib;
    B * pb2 = a->GetB();

    if (nullptr != pb2)
    {
        cout << "pb2 is not nullptr" << endl;
        //cout << pb2->GetX() << endl;
    }
    else
    {
        cout << "pb2 is nullptr" << endl;
    }

    if (nullptr != pb)
    {
        cout << "pb is not nullptr" << endl;
        //cout << pb->GetX() << endl;
    }
    else
    {
        cout << "pb is nullptr" << endl;
    }

    system("pause");
    return 0;
}

The codes are built in vs2015 with release(x86) mode. And here is the output:

pb2 is nullptr
pb is not nullptr

It is confusing that the pointer pb can pass the nullptr test. If I remove the annotation symbol // at line //cout << pb->GetX() << endl;, thus I get a memory crash at this line.

Why pb can pass the nullptr test?

Upvotes: 0

Views: 79

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409364

You can simplify the code a lot:

int a;
int *pa = &a;

The variable a exists, there's no doubt about it I hope. There's memory reserved for it by the compiler somewhere.

By using &a you get a pointer to the variable a, and that pointer can simply never be a null pointer.

It's the same in your code:

B ib;
B* pb = &ib;

The variable ib exists, no matter how you initialize it, and a pointer to it will never be a null pointer.


As for pb2 being a null pointer, it's because the GetB function returns a null pointer.

The GetB function can, with the current code, be simplified as

B* GetB() { return nullptr; }

When you then do

B* pb2 = a->GetB();

you simply initialize pb2 as a null pointer. It's equivalent to

B* pb2 = nullptr;

Upvotes: 5

Related Questions