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

前端 未结 7 659
余生分开走
余生分开走 2021-02-03 17:19

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

相关标签:
7条回答
  • 2021-02-03 17:49
    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] | ...
    
    0 讨论(0)
  • 2021-02-03 17:53
    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.

    0 讨论(0)
  • 2021-02-03 17:55

    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.

    0 讨论(0)
  • 2021-02-03 17:56

    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
    
    0 讨论(0)
  • 2021-02-03 18:00

    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.

    0 讨论(0)
  • 2021-02-03 18:12

    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.

    0 讨论(0)
提交回复
热议问题