Поля структуры появляются в памяти в том же порядке, в котором они идут вобъявлении структуры. Первое поле имеет тот же адрес, что и структура в целом. Каждое последующее поле располагается после предыдущего с учетом выравнивания.
Выравнивание указывает, что поле должно располагаться по адресу, которое кратно (делится без остатка) на выравнивание. Для примитивных типов и указателей выравнивание соответствует размеру типа. Например, размер типа int - 4 байт, соответственно поле age должно быть находиться по адресу, который кратен 4. Размер типа char - 1 байт, поэтому его выравание равно 1 байт, а поле типа char может располагаться по любому адресу. Размер типа long - 8 байт, поэтому его выравнивание равно 8. Размер указателей занимает 8 байт на 64-разрядных системах и 4 байта на 32-разрядных архитектурах. Соответственно выравнивание указателей - 8 или 4 байта в зависимости от разрядности системы.
#include <stdio.h> struct person { int age; char* name; }; int main(void){ struct person tom = {.age = 40, .name ="Tom"}; // получаем размер структуры person printf("sizeof(struct person): %lu\n", sizeof(struct person)); // получаем адрес переменной tom printf("tom address: %p\n", &tom); // получаем адрес поля age в переменной tom printf("age address: %p\n", &tom.age); // получаем адрес поля name в переменной tom printf("name address: %p\n", &tom.name); return 0; }
Согласно System V ABI, размер структуры должен быть кратен его выравниванию. ABI также утверждает, что структура принимает то же выравнивание, что и ее наибольшее поле. Так, в примере выше наибольшее поле структуры person - поле name занимает 8. Следовательно, вся структура должна быть выровнена по 8 байтов, а ее размер должен быть кратен 8.
Если поле представляет массив, то для него используется выравнивание типа его элементов