#include <stdio.h>
int main(void){
unsigned a[3][4] = {
{2,23,6,7},
{8,5,1,4},
{12,15,3,9}
};
printf("%u",*((int*)(((char*)a)+4)));
return 0;
}
The output in my machine is the value at a[0][1] i.e 23.Could somebody explain how is this working ?
Edit: Rolling Back to old yucky code,exactly what was presented to me 😛
So you have your array in memory as so:
What this does is cast the array to a
char*, which lets you access individual bytes, and it points here:It then adds four bytes, moving it over to the next value (more on this later).
Then it turns it into an
int*and dereferences it, getting the value 23.There are technically three things wrong with this code.
The first is that it assumes that an
unsignedis 4 bytes in size. (Hence the+ 4). But this isn’t necessarily true! Better would have been+ sizeof(unsigned), ensuring correctness no matter what sizeunsignedhappens to be.The second problem is the cast to
int: the original array wasunsigned, but the value is being cast to anint. There exists values in theunsignedrange thatintcannot represent (because in aninthalf of the range is in the negatives.) So if one of the values in the array was not representable as anint(meaning the value was greater thanINT_MAX), you’d get the wrong value. Better would be to convert tounsigned*, to maintain the correct type.The last thing is the format specifier. The specifier for integers is
%d, but the code uses%u, which is for unsigned integers. In effect, even though casting back toint*was wrong,printfis going to cast that value back into anunsigned*, restoring it’s integrity. By fixing problem two, problem three fixes itself.There is a hidden fourth problem: The code sucks. This may be for learning purposes, but yuck.