#include<stdio.h>
int main()
{
int *previous, *current ;
int a[5] = {1,2,3,4,5};
current =(int *) a ;
previous = current ;
current = *( (int**) current ) ; //my question is on this line
printf ("\nprevious is 0x%x and current is 0x%x \n ", previous , current ) ;
printf ("\nprev+1 0x%x , prev+4 0x%x \n", previous+1 , previous+4 ) ;
return 0;
}
and the output is :
bash-3.00$ ./a.out
previous is 0xffffd0f8 and current is 0x1
prev+1 0xffffd0fc , prev+4 0xffffd108
My question is: “current” was previously pointing to the start of the array, before it was referenced and dereferenced back again. How does the following statement change the value of “current”?
current = *( (int**) current ) ;
Also, if I print *previous it will print 1 while *current will core dump. What is the reason for this behaviour?
First, you cast
currentto anint**, so the value stored in thesizeof(int**)bytes starting at¤tare to be interpreted as the address of anint*. Then you dereference the pointer obtained from the cast. That means, theint**assumed to be stored there is followed, and thesizeof(int*)bytes at that address are stored incurrent.Now,
currentpointed to the first element of the arraya, so the bytes stored at the beginning ofaare copied intocurrent. Ifsizeof(int*) == sizeof(int), theintvalue 1 stored ina[0]is then interpreted as an address. Ifsizeof(int*) == 2*sizeof(int)(the other common occurrence), then the pointer value is composed of the twoints 1 and 2.previouspoints to the first element ofa, so dereferencingpreviousyields the value 1. Dereferencingcurrentnow tries to read anintfrom address 1 (it is undefined behaviour, so whatever else would happen wouldn’t violate the standard, but that’s the normal course of things), which normally isn’t accessible for the process.