Reputation: 349
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
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