0

Consider the code:

int main() {
    char orange[5];
    for (int i = 0; i < 5; i++)
        orange[i] = 1;
    printf("orange: %d\n", *((char *)orange));        
    printf("orange: %d\n", *((int *)orange)); 
    return 0;
}

The first print statement gives me a value of 1, but the second print statement gives me a value of 16843009. What is the reason for the difference?

rock321987
  • 10,942
  • 1
  • 30
  • 43
user3521929
  • 499
  • 1
  • 5
  • 9
  • I would guess that the second statement is taking the whole list and treating it as one giant int. So it may be treating orange as one long binary number. – Blake G Jun 24 '14 at 04:19

3 Answers3

5

In the second one you are aliasing some adjacent char values as int. This is undefined according to the C standard; however a common result is that you will get the value of int which has the same bit-pattern as the bit-pattern of those char values concatenated.

In this case the value you are seeing is the decimal form of 0x01010101 .

It is undefined behaviour because of C99 6.5#7 which lists the valid type combinations which may be aliased, and char as int is not in the list. (You can alias int as char, but not the other way around). See here to get the Standard text.

There is also potential undefined behaviour because of alignment requirements. For example, some systems require that int only be accessed at addresses which are multiples of 4.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • 1
    Hi @Matt, I didn't understand as why it is undefined behavior. It will be nice if you can explain it or give me some resource to read about it. – 0xF1 Jun 24 '14 at 04:21
2

In second case, you casted it to int pointer. Hence assuming int to be 4 bytes on your system, doing *((int *)orange) will access 4 bytes starting from orange[0] to orange[3].

Since you have all 1 in these address the hex notation of orange[0] to orange[3] will be 0x01010101 which is 16843009 in decimal.

0xF1
  • 6,046
  • 2
  • 27
  • 50
0

First you have to know int is a 4 bytes quantity, char is a 1 byte. When the machine read an integer, it will read consecutive 4 bytes. And read 1 byte for char. In your case, you first declare an array orange[5], which is consecutive 5 bytes on the machine. And you assign 1 for each byte. So you will get something like this on your machine

0000 0001 0000 0001 0000 0001 0000 0001 0000 0001

And variable orange is a pointer pointing to the first byte. If you cast orange to char * and dereference it, the machine will try to read a char on this address (orange), so you will get

0000 0001 

If you cast orange to int pointer, the machine will try to read 4 bytes starting from orange, so you will get this.

0000 0001 0000 0001 0000 0001 0000 0001

If you turn this binary number into decimal, you will get 16843009

Hope it helps :)

Timothy Leung
  • 1,407
  • 7
  • 22
  • 39