gcc sizeof (struct), дающий неожиданное значение - PullRequest
1 голос
/ 03 октября 2011

Я пишу программу для распаковки PE-файлов. У меня есть структура, Pe_SymbolHeader. Это выглядит так:

typedef struct _Pe_SymbolHeader {
    char Name[8];                // 8
    uint32_t Value;              // 12
    uint16_t SectionNumber;      // 14
    uint16_t Type;               // 16
    uint8_t  StorageClass;       // 17
    uint8_t  NumberOfAuxSymbols; // 18
} Pe_SymbolHeader;

gcc сообщает мне, что размер этой структуры составляет 20 байт.

printf("sizeof Pe_SymbolHeader %d\n", sizeof(Pe_SymbolHeader));

Я решил поместить Pe_SymbolHeader в стек и посмотреть, где все находится в памяти

Pe_SymbolHeader test

printf("%p\n", &(test.Name));
printf("%p\n", &(test.Value));
printf("%p\n", &(test.SectionNumber));
printf("%p\n", &(test.Type));
printf("%p\n", &(test.StorageClass));
printf("%p\n", &(test.NumberOfAuxSymbols));

Это дало мне следующее, что кажется нормальным:

0x7fffffffe150
0x7fffffffe158
0x7fffffffe15c
0x7fffffffe15e
0x7fffffffe160
0x7fffffffe161

Так что, если gcc использует 18 байтов для хранения моей структуры, почему sizeof сообщает мне, что структура займет 20 байтов?

Редактировать: Хорошо, похоже, что gcc пытается помочь мне, это то, что убивает меня, и несколько ответов верны. Я могу голосовать только за одного, но спасибо тем, кто ответил.

Ответы [ 4 ]

3 голосов
/ 03 октября 2011

Часть структуры uint32_t должна быть выровнена по кратному 4 байтам, поэтому размер структуры должен быть кратным 4 байтам, чтобы гарантировать, что массив структуры не вызовет проблем (неправильно выровнен проблема с доступом - которая может привести к ошибкам SIGBUS на некоторых машинах и (очень) неэффективному доступу на (большинстве) других машинах). Следовательно, компилятор назначает 2 байта заполнения в конце структуры; у них нет имени, поэтому вы не можете получить к ним законный доступ.

3 голосов
/ 03 октября 2011

Из-за заполнения для выравнивания


В конце структуры есть отступы.

Причина в том, что происходит в массиве или, возможно, в каком-то другом контексте, где что-то следует вашей структуре. Это может быть другой экземпляр этой структуры. Структура содержит 32-битный объект, поэтому она будет иметь требование выравнивания 32 бит.

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

2 голосов
/ 03 октября 2011

Итак, если gcc использует 18 байтов для хранения моей структуры, почему sizeof сообщает мне, что структура займет 20 байтов?То же самое для них обоих, это вас просветит.

1 голос
/ 03 октября 2011
uint32_t Value;

это добавляет 6 байтов в отличие от ожидаемых 4. Я склонен согласиться с Джонатаном Леффлером по поводу основных причин.

...