C Указатель Арифметический размер (структура) - PullRequest
7 голосов
/ 15 декабря 2011

Вот код, о котором идет речь

#include <stdio.h>

struct test {
    unsigned char t;
    unsigned short u;
    unsigned char v;
};


int main ()
{
    struct test  * a = (void *) 0x1000;

    printf("%x %p %p\n",
           sizeof(struct test),
           a + sizeof(struct test),
           a - sizeof(struct test));

    return 0;
}

sizeof (struct test) печатает 6, поэтому я бы ожидал , чтобы увидеть:

6 0xffa 0x1006

Вместо этого я получаю

6 0x1024 0xfdc

В прошлый раз, когда я проверял, 0x24 или 36 не было равно 6. Он даже не выровнен ни с чем, что я могу сказать.Я в полной растерянности.

Может кто-нибудь объяснить мне, почему я получаю эти значения?

Ответы [ 4 ]

17 голосов
/ 15 декабря 2011

Проблема в том, что при выполнении арифметики с указателем он увеличивается на кратное размера типа данных.

То, что вы фактически делаете, это добавление к квадрату sizeof(struct test).

Начиная с sizeof(struct test) = 6, вы увеличиваете адрес на 6 * 6 = 36. Следовательно, почему вы получаете 0x1024 и 0xfdc вместо 0x1006 и 0xffa. (Вы также переключили + и -, но это мелочь.)

Вместо этого просто сделайте это:

printf("%x %p %p\n",
       sizeof(struct test),
       a + 1,
       a - 1);
4 голосов
/ 15 декабря 2011

Когда вы делаете указательную арифметику, как это, вы перемещаетесь вперед или назад на такое количество элементов, как если бы эта переменная была в массиве.Поэтому вы действительно хотите просто использовать a + 1 и a - 1, которые должны каждый раз увеличиваться на 6 байтов.

ВАЖНО: Имейте в виду, что компилятор может добавить заполнение в вашей структуречтобы помочь с выравниванием.Не просто предполагайте, что, поскольку у вас есть два однобайтовых символа и двухбайтовый код, ваша структура будет иметь размер 4 байта - это не тот случай.(На самом деле, не думайте, что вы знаете размер char или short; раньше я видел 2-байтовые символы).

2 голосов
/ 15 декабря 2011

Я думаю, что вы ищете a + 1 и a - 1.

(a + x) - это то же самое, что &a[x].

1 голос
/ 15 декабря 2011

У вас есть напечатанный указатель.

Поэтому, когда вы увеличиваете его на 1 (то есть a + 1), это означает a + sizeof(type).

Итак a + sizeof(type) = a + sizeof(type) * sizeof(type) = a + 6 * 6 (в вашем случае как sizeof (test) = 6)

Вот откуда вы получаете 0x24 или 36 от.

...