Pankaj
Pankaj

Reputation: 3

Problem in understanding pointer to an Object set to NULL

Can any one explain what does it mean by making an pointer to an object to NULL?

When we assign ptr to an object to NULL, how can we still access the member function?

class A
{
public:
    void print()
    {
        cout<<"Hello";
    }
}

int main()
{
    A * a;
    A* b = NULL;

    a->print();
    b->print();
}

EDIT: Will the program crash? http://ideone.com/DudZ6

Upvotes: 0

Views: 132

Answers (3)

James Kanze
James Kanze

Reputation: 154047

You can't. Any attempt to dereference the pointer (any application of the * or -> operator to it) is undefined behavior, and may do anything. Most of the time, of course, you'll only crash if the code actually needs data from the object (including internal data like a vptr); otherwise, the code will seem to work. But that's just one of the possible undefined behaviors; I've actually used a compiler where your small program would crash.


As per C++ Standard:

1.9 Program execution
4:

Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing the null pointer). [Note: this International Standard imposes no requirements on the behavior of programs that contain undefined behavior. ]

So strictly, speaking the behavior is undefined, As many have pointed out in comments section just because it works on a particular platform does not make it legal.

So the as per the C++ standard the behavior of the code snippet is Undefined Behavior.

Upvotes: 5

dascandy
dascandy

Reputation: 7302

The pointer is used for accessing the members of that object. If your function(s) don't need to access any members and are not virtual, they actually don't use the object. The code is still strictly speaking invalid, but it won't crash.

If you replace the contents with printing the "this" pointer, it'll still work as you're not dereferencing it.

struct X { 
    void print() { 
        cout << "this pointer is " << this << endl; 
    } 
};

int main() {
    X *x;
    x->print(); // will print whatever was on the stack, ie, random garbage
    X *t = NULL;
    t->print(); // will print a null pointer
}

If you add one member variable and print that, or make the function virtual (so it will have to be looked up through the object itself) it will crash.

struct X { 
    virtual void print() { 
        cout << "Hello World" << endl; 
    } 
};

struct X2 { 
    int y;
    void print() { 
        cout << "y is " << y << endl; 
    } 
};

int main() {
    X *x = NULL;
    x->print(); // will crash on null pointer dereference
    X2 *x2 = NULL;
    x2->print(); // will crash on null pointer dereference
}

Upvotes: 5

sergio
sergio

Reputation: 69047

You can't,

   A* b = NULL;
 b->print();

this is undefined bahvior and could make your program crash with a segmentation fault (depending on the definition of your print method).

Generally speaking, assigning NULL to a pointer is used to give the pointer a value that means "this pointer is not set, do not use it". Take this code:

void function() {
   int* p;
   int* q = NULL:
   ... 
}

when the function is called, p and q are allocated on the stack; due to the way compiler works, p is left unassigned, that means that it gets the value that it is found on the stack at the moment of calling the function; this is a random value that usually has not much to do with your program.

Now, the fact that p has got a value could lead you into thinking that this value is "correct", so you use it; but, it is not (because it is random, due to not initializing the pointer), so you also get a crash or some kind of unexpected behavior.

In the case of q, the fact of assigning NULL to it allows you to tell that it has no usable value. So, you don't reference it:

 if (q != NULL) {
     q->....
 }

The idiom above does not work for p, so you have no way to tell whether it is ok.

In the end: always initialize your variable; in the case of pointers, if you do not have a vlaue to assign, assign NULL, so you know that pointer should not be dereferenced.

Upvotes: 1

Related Questions