Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does dereference a NULL pointer guarantee to crash a program in C/C++?

I come across this wired code and it's not crashing.

#include <stdio.h>
struct s
{
    char* c;
    char* c2;
};

int main()
{
    struct s* p = NULL;
    printf("%d\n", &(p->c));
    printf("%d\n", &p->c2);
    printf("%d\n", &(*p).c2);
    return 0;
}

Output:

0
4
4

I have several question comes to me I cannot answer:

  1. Does NULL pointer always equal to 0 in c/c++?

  2. What happen if 0 happen to be an address of a variable?

  3. It seems the outputs are offset addresses of members of the struct. How does this get calculated. I mean p->c is the address of c which doesn't exist because p == NULL. How come you can get address of the address of c by &p->c if the address of c doesn't exist?

  4. Does dereference a NULL pointer guarantee to crash a program in C/C++?(Let's assume in system)

like image 676
ycshao Avatar asked Apr 03 '14 19:04

ycshao


People also ask

Can crash the program by dereferencing a null pointer?

Dereferencing a null pointer always results in undefined behavior and can cause crashes. If the compiler finds a pointer dereference, it treats that pointer as nonnull. As a result, the optimizer may remove null equality checks for dereferenced pointers.

What happens when you dereference a pointer?

Dereferencing is used to access or manipulate data contained in memory location pointed to by a pointer. *(asterisk) is used with pointer variable when dereferencing the pointer variable, it refers to variable being pointed, so this is called dereferencing of pointers.

Can we dereference a null pointer in C?

Dereferencing a null pointer is undefined behavior. On many platforms, dereferencing a null pointer results in abnormal program termination, but this is not required by the standard.

Why will a segmentation fault occur when we dereference null?

To quote from Wikipedia: Dereferencing the NULL pointer typically results in an attempted read or write from memory that is not mapped - triggering a segmentation fault or access violation. This may represent itself to the developer as a program crash, or be transformed into an exception that can be caught.


2 Answers

No, dereferencing a null pointer doesn't guarantee a crash.

For one thing, in many cases, the compiler is able to optimize out the dereference operation. in your case, &(p->c) nominally dereferences a null pointer, but you then take the address of the result (after selecting a member of the pointed-to structure). Presumably the compiler replaces the entire expression by a number, which is the offset of the members within the structure. (There's no guarantee that a null pointer refers to address 0, or that it will be optimized in this manner, but it happens to do so on your system.)

This is the basis of a common implementation of the standard offsetof macro. It can't be implemented in portable standard C or C++, but implementations commonly use system-specific tricks like this -- which is perfectly valid as long as it yields the correct result on that system.

Second, even if you actually dereference a null pointer, the behavior is undefined. This might mean that your program crashes, but as far as the language standard is concerned it can do literally anything.

There have been systems in the past (and there probably still are) where a null pointer refers to address 0, and the system's memory map is set up so that address 0 is a valid memory address that happens to contain a 0 value. On such a machine, for example, a null pointer acts like a pointer to an empty '\0'-terminated character string. This led to a flurry of bug fixes when code that worked on such systems, and which unintentionally depended on that behavior, was ported to newer systems with stronger memory protection. (I think this may have been the transition from the 68K-based Sun 3 to the SPARC-based Sun 4, but I'm not sure of that.)

For more information on null pointers, see section 5 of the comp.lang.c FAQ. Most of it applies to C++ as well.

like image 195
Keith Thompson Avatar answered Oct 08 '22 22:10

Keith Thompson


You aren't actually dereferencing the pointer. That is why the code isn't crashing. What the code does is to get the offset of the struct members. The first member is at the offset of 0 bytes and the second at 4 bytes.

The c standard doesn't guarantee that NULL pointer is defined as 0, it is implementation defined. ( 201x: 7.19)

like image 44
this Avatar answered Oct 09 '22 00:10

this