I got surprised when the following program did not crash.
typedef struct _x {
int a;
char b;
int c;
} x;
main() {
x *ptr = 0;
char *d = &ptr->b;
}
As per my understanding the ->
operator has higher precedence over &
operator. So I expected the program to crash at the below statement when we try to dereference the NULL pointer tr
.
char *d = &ptr->b;
But the statement &ptr->b
evaluates to a valid address. Could somebody please explain where I'm wrong?
To access members of a structure using pointers, we use the -> operator. In this example, the address of person1 is stored in the personPtr pointer using personPtr = &person1; . Now, you can access the members of person1 using the personPtr pointer.
Array elements are accessed using the Subscript variable, Similarly Structure members are accessed using dot [.] operator. Structure written inside another structure is called as nesting of two structures.
Pointer to structure holds the add of the entire structure. It is used to create complex data structures such as linked lists, trees, graphs and so on. The members of the structure can be accessed using a special operator called as an arrow operator ( -> ).
Your expectations were unfounded. C programs don't necessarily "crash" when you dereference null pointers. C programs exhibit so called undefined behavior when you attempt to do something like that. Undefined behavior can manifest itself in many different ways. It can result in a crash. Or it can produce something that even resembles a "working" program. The latter is what apparently happened in your case.
But in any case, your program's behavior is undefined. And no, it does not produce a "valid address" as you seem to mistakingly believe. A numerical address that corresponds to a location in memory where no object exists is not valid (with the exception of null pointer value, of course).
The reason that your code doesn't crash is that you didn't actually dereference the pointer. Notice that the expression
&ptr->b
doesn't actually try loading the contents of ptr
or ptr->b
. Instead, it just stores the address of where this is located in memory. What you'll end up getting is a pointer to where the b
field of the object pointed at by ptr
should be. This will be a few bytes past address 0, so dereferencing the pointer you just created will cause a segfault.
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