Спасибо за размещение кода. Теперь я вижу проблему. Это из-за заполнения.Для остроумие:
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));
На моей машине это печатает
1
2
4
8
Вы могли бы подумать, не должен быть sizeof(struct st)
1 + 2 + 4 = 7
? Это, конечно, разумная мысль, но из-за alignment issues есть отступы между a
и c
. Таким образом, в памяти, структура выглядит следующим образом (по отношению к первому байту структуры):
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
Следовательно (по отношению к &s1
):
&s1.b - 1 is ((long)&s1.b) - sizeof(int) = 4 - 4 = 0 = &s1
Вот почему, как &s1
и &s1.b - 1
напечатает тот же адрес. В частности, если
&s1 = 0x804a01c
затем
&s1.b = 0x804a01c + 0x00000004 = 0x804a020
и
&s1.b - 1 = 0x804a020 - 0x00000004 = 0x804a01c
и
&s1.b - 2 = 0x804a020 - 0x00000008 = 0x804a018
Отметим, наконец, что это поведение конкретной реализации. Это не переносимо!
Наложение структуры определяется реализацией. –
@Prasoon: это не имеет ничего общего с прокладкой структуры: '& s1.b' является' int * ', а отступы в структуре не влияют на то, как арифметика указателя работает с' int * '. –
@Steve Jessop: Точно. Плюс один на ваш комментарий. – jason