Размер структуры C++: 2+4+2+2+4 = 16

Возможный дубликат:
Почему sizeof для структуры не равен сумме sizeof каждого члена?

Почему sizeof(); этой структуры 16 байтов? Я собираю в g++.

struct bitmapfileheader {       
     unsigned short bfType;
     unsigned int bfSize;
     unsigned short bfReserved1;
     unsigned short bfReserved2;
     unsigned int bfOffBits;   
   };

9 ответов

Это связано с тем, что 4-байтовые числа выровнены по 4-байтовой границе, поэтому после bfType есть 2 байта заполнения.

Выравнивание. Скорее всего, на вашей платформе должны быть выровнены 4 байта, а шорты - 2 байта.

+0 -1 : bfType
+2 -3 : <padding>
+4 -7: bfSize
+8 -9: bfReserve1
+10 -11: bfReserve2
+12 -15: bfOffBits
-------------
16 bytes

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

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

Если вы не хотите этого, вы можете использовать UNALIGNED макро.

Я думаю, что ваш компилятор использует 4-байтовое выравнивание для полей.

Эта проблема возникает из-за концепции, известной как выравнивание. Во многих случаях желательно, чтобы число размещалось по адресу, кратному размеру числа в байтах (до некоторого максимума, часто это размер указателя платформы). Помещенная переменная называется выровненной по n-байтовой границе, где n - это число. Точные эффекты этого зависят от процессора. Многие процессоры выполняют математику быстрее, если данные правильно выровнены. Некоторые из них даже не способны выполнять операции (иногда даже операции загрузки) с неподходящими данными: для работы с такими данными их необходимо загрузить в два регистра, а затем выполнить серию битовых сдвигов и масок, чтобы получить полезное значение, а затем его нужно вернуть обратно. Думайте об этом как о хранении половины int в каждом из двух ведер и необходимости собрать их вместе, чтобы использовать его, а не просто хранить целое int в одном ведре.

В вашем случае начальный bfType скорее всего, необходимо выровнять по 2-байтовой границе, в то время как bfSize Скорее всего, необходимо выровнять 4-байтовую границу. Компилятор должен учесть это, выровняв всю структуру по 4 байта и оставив 2 неиспользованных байта между bfType а также bfSize,

Однако при компиляции в одной и той же системе заполнение, вероятно, будет согласованным, возможно, в зависимости от параметров компилятора и конкретного используемого ABI (как правило, вы безопасны на той же платформе, если не пытаетесь сделать вещи несовместимыми). Вы можете свободно создать другую структуру с теми же первыми 5 членами, и они будут занимать 16 байтов другой структуры, в тех же позициях.

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

ISO C++03, 9.2[class.mem]/12:

Нестатические члены данных (не объединяющего) класса, объявленного без промежуточного спецификатора доступа, распределяются так, чтобы более поздние члены имели более высокие адреса в объекте класса. Порядок распределения нестатических элементов данных, разделенных спецификатором доступа, не определен (11.1). Требования выравнивания реализации могут привести к тому, что два смежных элемента не будут выделяться сразу после друг друга; то же самое касается требований к пространству для управления виртуальными функциями (10.3) и виртуальными базовыми классами (10.1).

Вы можете прагма упаковать структуру, чтобы избежать заполнения

Это связано с выравниванием - компилятор должен выполнить некоторые отступы.

Из -за того, как распределена память, после короткого

Другие вопросы по тегам