+1 vote
164 views
#include <stdio.h>

int main(void)

{
int i;
char *p=(char *)&i;
++p;
(*p)=2;
printf("%d",i);
return 0;
}
You can't be sure that the output will be 300. I'm getting two different outputs on two different systems.
Can you tell me what's the output of following code in the system where you're running this code?

#include <stdio.h>

int main(void)

{
int i;
printf("%d\n", i);
return 0;
}
@pratyush it can't be 300 , 2 things are there first uninitialized i variable and secondly when we make *p = 2.. it will make i as 512 not 300 [assuming initial i =0]
@Gate Mission 1: Yeah, if i is 0 initially, then output will be 512. No doubt about it. I was wondering the same that output can never be 300. So I asked the OP initial value of i in his system.

By the way I've found some interesting properties while working on this question. Can you explain why the output is 512 when i is initialized to 0?
@pratyush explained in answer. Check !

First edit is int i = 0; //else unexpected results due to garbage value.

char *p=(char *)&i;
++p;


In memory int i is stored as : [0000 0000] [0000 0000] [0000 0000] [0000 0000]   --> Assuming Little endian system (Right to Left is LSB to MSB ) and int size as 4 bytes.

Here first char pointer p is made to point i but typecasted to char pointer so will fetch only 8 bits from LSB of int i.

++p; makes p point to next byte. Then p will point to highlighted bit below i.e from there next 8 bits as char is of size 1 byte.

[0000 0000] [0000 0000] [0000 0000] [0000 0000]

(*p)=2;

This makes changes in memory as follows :

[0000 0000] [0000 0000] [0000 0010] [0000 0000]

Now if we try to print i its nothing but 512 as 9th bit from LSB is 1.

So output is 512.

selected
could you please explain the solution by initializing i to , say 44 (some value other than 0)?

What I want to understand:

Why initially (i.e. before incrementing) p will point to the 8 bits from LSB? Why not from MSB?

if i is 44 initially then it's stored as :

[0000 0000] [0000 0000] [0000 0000] [0010 1100]

After *p = 2 stmt, changes in memory are :

[0000 0000] [0000 0000] [0000 0010] [0010 1100]

So i is 2+ 23 + 25+ 2--> 556.

some confusions here:

1. If int is of 4 byte then all those 4 bytes have one memory address and not 4 different addresses for each byte?

2. and why pointer holding address from LSB of int i(whatever i containing)?

3. in this case ++p, increment according to char(1 Byte) or int(4 Byte), bcz pointer is typecasted into integer pointer but orignally is a char pointer?

@mint:

1. Every byte will have different address.

2. Apparently it depends on the endianness of the machine. Check this

3. I don't think p is typecasted to pointer to int. It's still a pointer to char. so p++ makes it point to the next byte. (*p) = 2 makes the value of this current byte pointed by p = 2.

@pratyush thank you for clearing the point.

yes, pointer is not typecasted into integer pointer

i think for char *p=(char *)&i; address of int i  is cast into char type address.

correct me, if i wrong.

@mint you are correct :)

@mint: I don't have a concrete answer on that, but I don't think address is being typecasted. I think address will remain same. Address of i can be held in a pointer to integer, but since we need it to be assigned it to pointer to char, we typecast the pointer. You can think like address of i is implicitly pointed to by a pointer to int, which you need to typecast to pointer to char.

You can try checking the output of following:

printf("%p %p %p %p %p", p, p+1, &i, ((char *) &i) + 1, &i + 1);
&i + 1 gives the next address according to the size of integer.
((char *) &i) + 1 gives the next address according to the size of char.


So, before type coversion, the pointer would have pointed to full int size block ( say 4 bytes ), now it will point to char size blocks (1 byte).

+1 vote