I was trying to understand void pointer typecasting in C. I wrote a program to try and create a segmentation fault, but I am not getting it. Can someone please explain to me why
Code:
#include <stdio.h>
typedef unsigned long U32;
int main()
{
void *obj;
U32 value = 25;
U32* ptr;
printf("*(ptr) : %lu\n", *(ptr));
obj = &value;
ptr = &value;
ptr++;
printf("*(U32 *)(obj) : %lu\n", *(U32 *)(obj));
printf("*((U32 *)(obj) + 1) : %lu\n", *((U32 *)(obj) + 1));
printf("*(U32 *)((U32 *)(obj) + 1) : %lu\n", *(U32 *)((U32 *)(obj) + 1));
printf("*(ptr) : %lu\n", *(ptr));
return 0;
}
Output :
*(ptr) : 458998657
*(U32 *)(obj) : 25
*((U32 *)(obj) + 1) : 3215085752
*(U32 *)((U32 *)(obj) + 1) : 3215085752
*(ptr) : 3215085752
The way I see it only the 2nd printf is legal as all others are referring to some uninitialized random memory and should cause a seg fault
UB is funny like that- the behaviour is undefined, not guaranteed segfault. The address of obj + 1
is probably some other spot on the stack which is allocated to your program anyway. To get an almost guaranteed segfault, just de-reference obj
before it has ever been assigned.
U32* ptr;
printf("*(ptr) : %lu\n", *(ptr));
ptr
is uninitialized so it is undefined behavior to dereference it,
obj = &value;
ptr = &value;
ptr++;
printf("*(U32 *)(obj) : %lu\n", *(U32 *)(obj));
Ok, as long as obj
is pointing to a valid U32 (and U32 has to be an unsigned long as you're using %lu as the printf format)
printf("*((U32 *)(obj) + 1) : %lu\n", *((U32 *)(obj) + 1));
You're trying to dereference a pointer that points one U32 past any valid location, so it's undefined behavior.
printf("*(U32 *)((U32 *)(obj) + 1) : %lu\n", *(U32 *)((U32 *)(obj) + 1));
Same as above.
printf("*(ptr) : %lu\n", *(ptr));
Since you incremented ptr
, it points one U32 past anything valid, which leads to undefined behavior.
As your code does things that invokes undefined behavior , it's really hard and often impossible to reason about what is going to happen. It's undefined. Something unexpected could happen. Something bad could happen. Nothing bad could happen, and so on. Doing something in C that you should not do, does not mean it will segfault.
ptr
points to a valid object ( value
) but ptr++
does not point to an object. So accessing the element *ptr
after the pointer increment is undefined behavior. printf
of *ptr
can display random data but can also crash your program.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.