Thank you for posting your code. Now I see the issue. It is because of padding. To wit:
printf("sizeof(char): %d\n", sizeof(char));
printf("sizeof(short): %d\n", sizeof(short));
printf("sizeof(int): %d\n", sizeof(int));
printf("sizeof(struct st): %d\n", sizeof(struct st));
On my machine this prints
1
2
4
8
You might think, shouldn't sizeof(struct st)
be 1 + 2 + 4 = 7
? That's certainly a reasonable thought but because of alignment issues there is padding between a
and c
. Therefore, in memory, the struct looks like the following (relative to the first byte of the struct):
0x00000000: char a
0x00000001: padding
0x00000002: first byte of short c
0x00000003: second byte of short c
0x00000004: first byte of int b
0x00000005: second byte of int b
0x00000006: third byte of int b
0x00000007: fourth byte of int b
Consequently (relative to &s1
):
&s1.b - 1 is ((long)&s1.b) - sizeof(int) = 4 - 4 = 0 = &s1
This is why both &s1
and &s1.b - 1
will print the same address. In particular if
&s1 = 0x804a01c
then
&s1.b = 0x804a01c + 0x00000004 = 0x804a020
and
&s1.b - 1 = 0x804a020 - 0x00000004 = 0x804a01c
and
&s1.b - 2 = 0x804a020 - 0x00000008 = 0x804a018
Note, finally, that this is implementation-specific behavior. This is not portable!