Сколько байтов занимает char, определенный в структуре? - PullRequest
3 голосов
/ 18 января 2012

Когда я определяю тип символа в структуре, кажется, что он занимает более 1 байта; на самом деле, кажется, занимает 4 байта.

Ниже моя программа:

#include <stdio.h>

int main(void)
{
    struct book{
        char name;
        float price;
        int pages;
    };
    struct book b1={'B',130.00,550};
    printf("\nAddress of structure:%u",&b1);
    printf("\nAddress of character name:%u",&b1.name);
    printf("\nAddress of float price:%u",&b1.price);
    printf("\nAddress of integer pages:%u",&b1.pages);
    printf("\n\n");
    return 0;
}

Когда я запускаю вышеуказанную программу, я получаю вывод ниже:

    Address of structure:557762432
    Address of character name:557762432
    Address of float price:557762436
    Address of integer pages:557762440

Почему я вижу разницу в 4 байта между адресом переменной "имя" и переменной "цена"?

Система, в которой выполняется эта программа, - x86_64 bit arch, работающая под управлением Fedora-14.

Ответы [ 4 ]

11 голосов
/ 18 января 2012

Стандарт C позволяет реализациям добавлять дополнительные биты заполнения к структурам, чтобы быстрее получать доступ к структуре, выравнивая ее по границам байтов, как того требует реализация.

Это известно как заполнение структуры .

Учитывая вышеизложенное, размер структуры может не совпадать с суммой размеров отдельных элементов.Вы всегда должны использовать sizeof, чтобы определить размер структуры.

Кроме того, вышеупомянутое является причиной того, что вы не видите членов структур, размещенных по адресам памяти, которые вы ожидаете от них.

3 голосов
/ 18 января 2012

Вы сталкиваетесь с правилами выравнивания. Это очень специфичная для компилятора и системы вещь, но по умолчанию (то есть, если вы не укажете иное, используя флаги компилятора или специальные запросы выравнивания в коде) GCC в x64 Linux выравнивает каждое поле структуры по кратному его размеру , Таким образом, односимвольному байту не нужно беспокоиться о выравнивании. Однако int или float всегда размещаются на 4-байтовой границе, а double всегда помещается на 8-байтовой границе. Это то, что вы видите здесь.

Как отмечает Этан выше в комментариях, некоторые процессоры даже не обращаются к объектам памяти, которые не выровнены определенным образом, а процессоры Intel будут обращаться к памяти гораздо медленнее, если она не выровнена.

0 голосов
/ 18 января 2012

"char" в C обычно занимает ровно 8 бит (один байт).

Однако, символ в структуре "выровнен" по границе слова, слова или даже четырех слов:

http://en.wikipedia.org/wiki/Data_structure_alignment

Существуют директивы компилятора для принудительного выравнивания до 4, 2 или 1 байта (что обходит это поведение).

Например, в Visual C ++ можно сказать «#pragma pack (1)».

0 голосов
/ 18 января 2012

Строго говоря, char всегда занимает один байт, но за ним может следовать заполнение 0 или более байтов.Степень заполнения зависит от компилятора и процессора, а также от выравнивания типа, следующего за char в структуре, и любых действующих прагм упаковки.Если N-байтовый тип должен быть выровнен по N-байту, как, например, в SPARC, то:

struct s16 { char c; double d; };
struct s8  { char c; long l;   };
struct s4  { char c; short s;  };
struct s2  { char c; char b;   };

За одиночным char следуют 7, 3, 1 и 0 байтов в структурахвыше на машине SPARC, а также на машине x86_64.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...