I've learned pointer to pointer.
I am curious about dereferencing after casting "integer to pointer" (char*)(int)
and "void pointer to pointer to char pointer." (char**)(void*)
Now there are some issues when I want to dereference to void pointer to pointer to char pointer.(char**)(void*)
I tried 2 cases.
integer to pointer (char*)(int)
#include <stdio.h>
int main()
{
int a = 10;
int b;
void* ptr = &a;
b = ptr;
printf("%d\n", *(unsigned int*)b);
printf("%d\n", *(void**)(b));
printf("%p\n", *(char**)(b));
return 0;
}
*(unsigned int*)b
*(void**)(b)
*(char**)(b)**
These three read 10 which is in address.
But the code below is problem. (Please watch ptr_speacial)
"void pointer to pointer to char pointer." (char**)(void*)
#include <stdio.h>
int main()
{
int arr[5] = { 1,2,3,4,5 };
char arr2[5] = { 1,2,3,4,5 };
void* ptr_arr;
void* ptr_arr2;
void* ptr_special;
ptr_arr = arr;
ptr_arr2 = arr2;
ptr_special = (char*)ptr_arr2 + 4;
printf("address : %p: value : %d\n", ptr_special, *(char**)ptr_special);
printf("%d\n", *(char**)ptr_arr);
return 0;
}
*(char**)ptr_special
did not read 5 which is in address but -858993659
I'm not sure but I think this is overflow problem. What happend in this case? Please help me!
Take a look at this:
#include <stdio.h>
int main()
{
char arr2[] = { 1,2,3,4,5 };
char arr3[] = { 1,2,3,4,5 };
void* ptr_special2 = arr2 + 4;
void* ptr_special3 = arr3 + 4;
printf("address : %p: value : %d\n", ptr_special2, *(char**)ptr_special2);
printf("address : %p: value : %d\n", ptr_special2, *(char**)ptr_special3);
return 0;
}
output (may vary):
address : 0x7ffc5841755a: value : 50462981
address : 0x7ffc5841755a: value : 1074892805
Now try this:
char arr2[] = { 1,2,3,4,5,0,0,0 };
char arr3[] = { 1,2,3,4,5,1,0,0 };
output:
address : 0x7fffecb291fc: value : 5
address : 0x7fffecb291fc: value : 261
Try to work out what's happening before reading the ...
On my system, a "pointer to a pointer to a char" is 4 bytes long. So - when you take the address of the 5
in arr2
, cast it to a char**
, and dereference it - the system reads 4 bytes, starting at the 5
.
In arr2
, those 4 bytes are 5 0 0 0
, which in a little-endian system is interpreted as 5.
In arr3
, those 4 bytes are 5 1 0 0
, which in a little-endian system is interpreted as 5 + 256 = 261.
In your code, the three bytes after the 5
are unknown. You don't know what the compiler has placed there (if anything). You are reading beyond the end of the array because you are trying to read 4 bytes (or whatever sizeof(char**)
is on your system) from an array that only has 1 valid byte at that address.
This is undefined behaviour, which means the standard allows literally anything to happen - but typically, you could expect: