My char pointer points to invalid value after being cast from int*

CArraysPointers

C Problem Overview


I am learning C programming language, I have just started learning arrays with pointers. I have problem in this question, I hope the that output must be 5 but it is 2, Can anyone please explain why?

int main(){
   int arr[] = {1, 2, 3, 4, 5};
   char *ptr = (char *) arr;
   printf("%d", *(ptr+4));
   return 0;
}

C Solutions


Solution 1 - C

Assumed a little endian architecture where an int is 32 bits (4 bytes), the individual bytes of int arr[] look like this (least significant byte at the lower address. All values in hex):

|01 00 00 00|02 00 00 00|03 00 00 00|04 00 00 00|05 00 00 00

char *ptr = (char *) arr;

Now, ptr points to the first byte - since you have casted to char*, it is treated as char array onwards:

|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
 ^
 +-- ptr

Then, *(ptr+4) accesses the fifth element of the char array and returns the corresponding char value:

|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
         ^
         +-- *(ptr + 4) = 2

Hence, printf() prints 2.

On a Big Endian system, the order of the bytes within each int is reversed, resulting in

|0|0|0|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5
         ^
         +-- *(ptr + 4) = 0

Solution 2 - C

It's because the size of char is one, and the size of int is four. This means that adding 4 to ptr makes the result point to the second entry in the int array.

If you compiled this on a big endian system you would have printed 33554432 instead.

Solution 3 - C

int main(){
 int arr[] = {1,2,3,4,5};
 char *ptr = (char *) arr;
 printf("%d",*(ptr+4));
 return 0;
}

Each case of arr has sizeof(int) size (which may be 4 on your implementation).

Since ptr is a pointer to char, pointer arithmetic makes ptr + 4 points 4 bytes after &arr[0], which may be &arr[1].

In memory, it looks like something like:

Address | 0 1 2 3 | 4 5 6 7 | ...
Value   |  arr[0] |  arr[1] | ...

Solution 4 - C

On a 32 bit platform, int is four times the size of char. When you add 4 to ptr, you add 4 times the size of what ptr points to to ptr (which itself is a memory location). That happens to be the address of the second element in the int array.

On a 64 bit platform, int is eight times the size of char; and your output would be very different.

To cut a long story short, your code is not portable, (also see Joachim Pileborg's answer re endianness) but amusing to unpick.

Solution 5 - C

What you do is definitely not recommended in production code, but is definitely great for understanding pointers, casts, etc. in the learning process, so for this your example is great. So, why you get 2. It is because your array is an array of ints, which depending on your architecture has different size (in your case, sizeof(int) is 4). You define ptr as being a char pointer, char has size 1 byte. Pointer arithmetics (that's what you do when you write ptr+4) works with size of objects the pointer references, in your case with chars. Thus ptr+4 is 4 bytes away from the beginning of your array, and thus at the 2nd position of your int array. That is it. Try ptr+5, you should get 0.

Solution 6 - C

Since you are coverting int* to char*, ptr[0] = 1, ptr[4] = 2, ptr[8] = 3, ptr[12] = 4 , ptr[16] = 5 and all others equal to 0. ptr+4 points to 4th element in the ptr array. So result is 2.

Solution 7 - C

int main(){
 int arr[] = {1,2,3,4,5};
 char *ptr = (char *) arr;
 printf("%d",*(ptr+4));
 return 0;
}

Imagine arr is stored at the address 100 (totally dumb address). So you have: arr[0] is stored at the address 100. arr[1] is stored at the address 104. (there's is +4 because of the type int) arr[2] is stored at the address 108. arr[3] is stored at the address 112. Etc etc.

Now you're doing char *ptr = (char *) arr;, so ptr = 100 (the same as arr). The next statement is interesting, specially the second argument of printf : *(ptr+4). Keep in my mind that ptr = 100. So ptr + 4 = 104, the same address that arr[1] ! So it will print the value of arr[1], which is 2.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMayank TiwariView Question on Stackoverflow
Solution 1 - CAndreas FesterView Answer on Stackoverflow
Solution 2 - CSome programmer dudeView Answer on Stackoverflow
Solution 3 - Cmd5View Answer on Stackoverflow
Solution 4 - CBathshebaView Answer on Stackoverflow
Solution 5 - CondrejdeeView Answer on Stackoverflow
Solution 6 - CdijkstraView Answer on Stackoverflow
Solution 7 - CnouneyView Answer on Stackoverflow