Все размеры объектов в C и C ++ определены в терминах байтов , а не битов . Байт - это наименьшая адресуемая единица памяти на компьютере. Бит представляет собой одну двоичную цифру, 0
или 1
.
На большинстве компьютеров байт составляет 8 бит (поэтому байт может хранить значения от 0 до 256), хотя компьютеры существуют с другими размерами байтов.
Адрес памяти идентифицирует байт , даже на 32-битных машинах. Адреса N и N + 1 указывают на два последующих байта.
Значение int
, которое обычно составляет 32 бита, охватывает 4 байта, что означает, что существует 4 различных адреса памяти, каждый из которых указывает на часть int
.
В 32-разрядной машине все 32 фактически означает, что ЦП предназначен для эффективной работы с 32-разрядными значениями и что адрес имеет длину 32 бита. Это не означает, что память может быть адресована только в 32-битных блоках.
ЦП все еще может адресовать отдельные байты, что полезно, например, при работе с char
с.
Что касается вашего примера:
struct st
{
int a;
char c;
};
sizeof(st)
возвращает 8 не потому, что все структуры имеют размер, кратный 4, а из-за выравнивания . Чтобы процессор мог эффективно прочитать целое число, оно должно быть расположено по адресу, который делится на размер целого числа (4 байта). Таким образом, int
можно разместить по адресу 8, 12 или 16, но не по адресу 11.
A char
требует, чтобы его адрес делился только на размер char
(1), поэтому его можно разместить на любом адресе.
Теоретически, компилятор мог бы дать вашей структуре размер 5 байт ... За исключением того, что это не сработало бы, если вы создали массив st
объектов.
В массиве каждый объект размещается сразу после предыдущего без заполнения. Таким образом, если первый объект в массиве размещен по адресу, кратному 4, то следующий объект будет размещен по адресу, превышающему 5 байт, что не будет делиться на 4, и поэтому вторая структура в массиве не будет правильно выровнен.
Чтобы решить эту проблему, компилятор вставляет заполнение в структуру, так что ее размер становится кратным требованию выравнивания.
Не потому, что невозможно создать объекты, размер которых не кратен 4, а потому, что одному из членов вашей структуры st
требуется 4-байтовое выравнивание, и поэтому каждый раз, когда компилятор размещает int
в памяти, он должен убедиться, что находится по адресу, который делится на 4.
Если вы создадите структуру из двух char
с, она не получит размер 4. Как правило, она получит размер 2, потому что, когда она содержит только char
с, объект может быть помещен в любой адрес, и поэтому выравнивание не является проблемой.