Почему sizeof показывает в этом коде 8 байт?
int имеет 4 байта
char имеет 1 байт
Почему sizeof не показывает 5 байт?
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
struct test
{
int num;
char ch;
};
printf("%lu", sizeof(struct test));
return 0;
}
Я думал, что sizeof показывает 5, но он показал 8 байт.
Прочтите stackoverflow.com/questions/119123/…
и правильный спецификатор формата для sizeof() — %zu, использование неправильного спецификатора формата вызывает UB
Наблюдать:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
struct test
{
int num;
char ch;
};
struct test2
{
int num;
char ch;
} __attribute__((packed));
printf("%d\n", (int)sizeof(struct test));
printf("%d\n", (int)sizeof(struct test2));
return 0;
}
stieber@gatekeeper:~ $ gcc Test.c && ./a.out
8
5
В первой версии используется «заполнение», поэтому такие вещи, как выделение памяти для массива из 10 тестовых структур простым выполнением 10*sizeof(test)
, по-прежнему будут обеспечивать эффективное расположение памяти.
Невыровненный доступ, например, доступ к 4-байтовому целому числу в ячейке памяти, не находящейся на 4-байтовой границе, менее эффективен, а на некоторых платформах даже приводит к сбою.
Обратите внимание, что attribute
— это расширение gcc. Компиляторы нередко предлагают его, но стандарта не существует, поэтому другим компиляторам нужно что-то еще.
Кстати, именно поэтому порядок членов структуры может быть проблемой:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
struct test1
{
char ch;
int num;
char ch2;
};
struct test2
{
int num;
char ch;
char ch2;
};
struct test3
{
char ch;
char ch2;
int num;
};
printf("%d\n", (int)sizeof(struct test1));
printf("%d\n", (int)sizeof(struct test2));
printf("%d\n", (int)sizeof(struct test3));
return 0;
}
stieber@gatekeeper:~ $ gcc Test.c && ./a.out
12
8
8
Как видите, первый занимает больше памяти, чем второй, хотя фактические данные «те же». Это связано с тем, что компилятор должен переместить член int
к 4-байтовой границе, поэтому он вставляет 3 байта заполнения после char
(это всегда работает при условии, что сама структура размещена в месте, которое удовлетворяет всем требованиям выравнивания).
Если мы соединим оба члена 'char' вместе, компилятору не нужно будет добавлять дополнительные отступы, поскольку для эффективности char
не предъявляются особые требования к выравниванию.
Re "printf("%d\n", (int)sizeof ... );
", Правда? Вот как вы это исправили после того, как дали правильное исправление? Должно быть printf("%zu\n", sizeof ... );
Заполнение из-за выравнивания.