Почему размер этой структуры 24?
У меня есть структура, из которой я хочу рассчитать ее размер:
#pragma pack(push,4)
struct MyStruct
{
uint32_t i1; /* size=4, offset=0. */
uint32_t i2; /* size =4 offset =4 */
uint16_t s1; /* size =2 offset=8 */
unsigned char c[8]; /* size=8 offset=12*/
uint16_t s2; /* size=2 offset=20. */
uint16_t s3; /* size=2 offset=24. */
} ; // total size is 26
static_assert(sizeof(MyStruct) == 24, "size of MyStruct incorrect");
#pragma pack(pop)
Статическое утверждение показывает, что размер равен 24, но мой расчет показывает, что он должен быть 26.
Почему размер 24?
Я работаю над Windows 7, 32-битное приложение с использованием Visual Studio 2012
3 ответа
Выравнивание uint16_t
только 2, следовательно смещения:
#pragma pack(push,4)
struct MyStruct
{
uint32_t i1; /* offset=0 size=4 */
uint32_t i2; /* offset=4 size=4 */
uint16_t s1; /* offset=8 size=2 */
unsigned char c[8]; /* offset=10 size=8 */
uint16_t s2; /* offset=18 size=2 */
uint16_t s3; /* offset=20 size=2 */
/* offset=22 padding=2 (needed to align MyStruct) */
} ; // total size is 24
Редактировать Заполнение в конце необходимо, чтобы все элементы
MyStruct A[10]; // or
MyStruct*B = new MyStruct[10];
выровнены соответствующим образом. Это требует, чтобы sizeof(MyStruct)
это кратное alignof(MyStruct)
, Вот, sizeof(MyStruct)
= 6 *alignof(MyStruct)
,
любой struct
/class
Тип всегда дополняется до следующего кратного его выравнивания.
В дополнение к ответу Уолтера рассмотрите возможность ловить эту рыбу самостоятельно. Все, что вам нужно, это функция printf и простая арифметика:
struct MyStruct ms;
printf("sizeof(ms): %zd\n", sizeof(ms));
printf("i1\t%td\n", (uint8_t*)&ms.i1 - (uint8_t*)&ms);
printf("i2\t%td\n", (uint8_t*)&ms.i2 - (uint8_t*)&ms);
printf("s1\t%td\n", (uint8_t*)&ms.s1 - (uint8_t*)&ms);
printf("c \t%td\n", (uint8_t*)&ms.c - (uint8_t*)&ms);
printf("s2\t%td\n", (uint8_t*)&ms.s2 - (uint8_t*)&ms);
printf("s3\t%td\n", (uint8_t*)&ms.s3 - (uint8_t*)&ms);
(%zd
для печати size_t
, %td
для печати ptrdiff_t
, Равнина %d
вероятно, будет работать нормально на большинстве систем.)
Выход:
sizeof(ms): 24
i1 0
i2 4
s1 8
c 10
s2 18
s3 20
4 4 2 8 2 2 - будут упакованы как:
4 4 4 8 2 2 - последние два объединяются в 4 байта. третий элемент требует заполнения, последний и последний - нет.