Содержание

выравнивание и поля в памяти

https://metanit.com/c/tutorial/6.9.php

выравнивание в структурах

Поля структуры появляются в памяти в том же порядке, в котором они идут вобъявлении структуры. Первое поле имеет тот же адрес, что и структура в целом. Каждое последующее поле располагается после предыдущего с учетом выравнивания.

Выравнивание указывает, что поле должно располагаться по адресу, которое кратно (делится без остатка) на выравнивание. Для примитивных типов и указателей выравнивание соответствует размеру типа. Например, размер типа 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.

Выравнивание массивов

Если поле представляет массив, то для него используется выравнивание типа его элементов