2009-12-03 8 views
35

Можно создать дубликат:
Why isn’t sizeof for a struct equal to the sum of sizeof of each member?размер структуры в C

Рассмотрим следующий код C:

#include <stdio.h>  

struct employee 
{ 
    int id; 
    char name[30]; 
}; 

int main() 
{ 
    struct employee e1;  
    printf("%d %d %d", sizeof(e1.id), sizeof(e1.name), sizeof(e1)); 
    return(0); 
} 

Выходной сигнал является:

Почему размер структуры не равен сумме размеров отдельных переменных компонента?

+1

Вы можете использовать атрибут, упакованный в gcc .. Это отменит заполнение и сохранит структуру как можно меньше. struct test_t { int c; } __attribute __ ((__ packed__)); – eaanon01

+0

Дубликат (по крайней мере) http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member – dmckee

+6

eaanon01 , вы не должны рассказывать никому о чем-то, что невозможно, поскольку атрибут упакован, если нет действительно действительно веской причины, и все последствия понятны. –

ответ

52

Компилятор может добавлять дополнения для выравнивания. Обратите внимание, что это относится не только к заполнению между полями структуры, но также может применяться к концу структуры (так что массивы структурного типа будут правильно выровнены по каждому элементу).

Например:

struct foo_t { 
    int x; 
    char c; 
}; 

Даже если c поле не нужно отступы, то структура обычно будет иметь sizeof(struct foo_t) == 8 (на 32-битной системе - скорее система с 32-битным int типа), потому что после поля c должно быть 3 байта заполнения.

Обратите внимание, что отступ может не требоваться системой (например, x86 или Cortex M3), но компиляторы могут по-прежнему добавлять ее по соображениям производительности.

+1

+1, хотя выравнивание по 6 байт звучит странно. Может быть, я немного отстаю в низкоуровневых вещах. –

+1

Ну, имя начинается со смещения 4 (правдоподобно) и продолжается до 34. 34 не кратно 4, так что оно заканчивается на 36, что равно 9 * 4. Имеет смысл для меня! –

+2

Его выравнивание до 32-битных границ (4,8,16,24,32,36, ...) – Mordachai

0

выравнивая до 6 байт это не странно, потому что совместив с адреса, кратного до 4.

Так в основном у вас есть 34 байт в вашей структуре и следующая структура должна быть помещена по адресу, который кратен 4. Ближайшее значение после 34 равно 36. И эта область заполнения учитывает размер структуры.

2

Как уже упоминалось, компилятор C добавит дополнение для требований к выравниванию. Эти требования часто связаны с подсистемой памяти. Некоторые типы компьютеров могут получать доступ только к памяти, выстроенной до некоторого «хорошего» значения, например 4 байта. Это часто совпадает с длиной слова. Таким образом, компилятор C может выравнивать поля в вашей структуре с этим значением, чтобы упростить их доступ (например, 4 байтовых значения должны быть выровнены по 4 байт). Кроме того, он может вставить нижнюю часть структуры для выстраивания в линию данных, которые следуют структуре , Я считаю, что есть и другие причины. Более подробную информацию можно найти на странице this wikipedia.

1

Выравнивание по умолчанию, вероятно, 4 байта. Либо 30-байтовый элемент получил 32, либо структура в целом была округлена до следующего 4-байтового интервала.