What part of dereferencing NULL pointers causes un

2020-04-15 11:11发布

I am curious as to what part of the dereferencing a NULL ptr causes undesired behavior. Example:

//  #1
someObj * a;
a = NULL;
(*a).somefunc();   // crash, dereferenced a null ptr and called one of its function
                   // same as a->somefunc();

//  #2
someObj * b;
anotherObj * c;
b = NULL;
c->anotherfunc(*b);   // dereferenced the ptr, but didn't call one of it's functions

Here we see in #2 that I didn't actually try to access data or a function out of b, so would this still cause undesired behavior if *b just resolves to NULL and we're passing NULL into anotherfunc() ?

标签: c++
16条回答
来,给爷笑一个
2楼-- · 2020-04-15 12:06

It would still cause a crash because you're still instructing the compiler to attempt to access the memory at location 0 (which is forbidden). Depending on the signature of anotherfunc, you may be passing a reference (which are forbidden from being initialized with a NULL object), or a copy of *b.

查看更多
祖国的老花朵
3楼-- · 2020-04-15 12:12

That depends on the declaration of anotherfunc()

someObj * b;
anotherObj * c;
b = NULL;
c->anotherfunc(*b); 

If anotherfunc() accepts a reference to b then you have not de-referenceed b, you have just converted it into a reference. If on the other hand it is a value parameter then a copy constructor will be invoked and then you have de-referenced it.

Weather it will crash will depend on many factors (like if it has members). But the act of de-referencing on a NULL is undefined so it has the option of working on your compiler.

As for the first option of calling a method on a NULL pointer.
This also is undefined behavior. Weather it crashes will depend on the compiler and OS. But it is perfectly valid to not crash (the behavior is undefined).

A lot of confusion is derived because people refer to the * in *b as de-reference operator. This may be its common name but in the standard it is the 'unary * operator' and it is defined as:

5.3.1

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.

So the 'unary * operator' returns a reference to the object that was pointed at by the pointer it was applied to. (No de-referencing has happened at this point).

查看更多
贪生不怕死
4楼-- · 2020-04-15 12:15

It would still cause a crash, but that's not necessarily undesired behaviour. Part of the usefulness of NULL is that, on most platforms, it points to memory that is explicitly inaccessible to your application, and causes a segmentation fault (or access violation) the very moment you try to dereference it.

Its purpose is to explicitly mark the contents of pointers as invalid.

查看更多
叼着烟拽天下
5楼-- · 2020-04-15 12:16

Tom's comment is correct, I did not initialize correctly therefore the question is ambiguous at best yet most everyone directly answered my question, I unwittingly submitted the question while not logged in (sorry I'm new to stackoverflow) so can someone with editing powers update the OP?

//  #2
someObj * b;
anotherObj * c = new anotherObj();        //initialize c
b = NULL;
c->anotherfunc(*b);   // *b is in question not the c dereference
查看更多
登录 后发表回答