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:
Does NULL pointer always equal to 0 in c/c++?
What happen if 0 happen to be an address of a variable?
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?
Does dereference a NULL pointer guarantee to crash a program in C/C++?(Let's assume in system)
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.
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.
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.
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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With