Используйте самый простой и понятный метод для вычисления размера struct.

Вычисление размера struct должно следовать принципу байтового выравнивания.

По умолчанию байтовое выравнивание struct обычно удовлетворяет трём правилам:

  • 1) Первый адрес переменной struct должен быть кратен размеру её самого широкого члена фундаментального типа;
  • 2) Смещение каждого члена относительно первого адреса struct кратно размеру этого члена; при необходимости компилятор добавляет байты заполнения между членами (внутреннее добавление);
  • 3) Общий размер struct кратен размеру её самого широкого члена фундаментального типа; при необходимости компилятор добавляет байты заполнения после последнего члена (хвостовое заполнение).

На самом деле, пока что забудьте об этих трёх правилах. В моём методе достаточно запомнить только третье: размер struct должен быть кратен наибольшему размеру в байтах среди её членов.

Сначала рассмотрим две структуры struct, определённые ниже:

struct {   char a;   short b;   char c; }S1;

struct {  char  a;  char  b;  short c; }S2;

Соответственно получено при тестировании программы:sizeof(S1)=6 , sizeof(S2)=4。

Примечание: почему простое изменение порядка членов struct даёт разные результаты?

Решение:

  • (1) Сначала найдите наибольший размер в байтах среди переменных-членов. Видно, что для S1 и S2 наибольшим является short, который занимает 2 байта;
  • (2) Следовательно, с этого момента за стандарт принимаются 2 байта. То есть каждый член требует не более 2 байт, а остальное заполняется как заполнители. Обратите внимание, что на диаграмме ниже одна ячейка представляет один байт;
  • (3) Итак, сначала нарисуйте 2 ячейки, затем посмотрите на порядок членов и увеличивайте шаг за шагом, каждый раз используя 2 как основу приращения.
Для S1 порядок таков:char->short->char :

Итак, для S1 размер структуры равен 2*3=6. Что касается того, почему дополнительный байт второго char не отбрасывается, это следует третьему правилу: размер структуры должен быть целым кратным наибольшему размеру в байтах среди членов.

S1=2*3=6

Для S2 также нарисуйте диаграмму, но порядок таков:char->char->short:

S2=2*2=4

Используя этот метод, рассмотрим другую структуру, подобную этой:

struct stu1
{
    int i;
    char c;
    int j;
};

Очевидно, наибольший размер в байтах равен 4. Порядок: int char int:

Поскольку int занимает 4 байта, а char уже занимает 1, чего недостаточно, эти 3 байта должны быть дополнительными заполнителями.

Stu1=3*4=12

Что, если мы это изменим?

struct stu2
{
    int i;
    int j;
    char  c;
};
Stu2=3*4=12

Рассмотрим другой пример: когда переменная-член структуры является другой структурой, просто добавьте структуру-член целиком.

typedef struct A
{
    char a1;
    short int a2;
    int a3;
    double d;
};

A=16

typedef struct B
{
    long int b2;
    short int b1;
    A a;
};

Для B сначала игнорируйте A a, то есть удалите член A a и вычислите размер структуры B как 8, поэтому окончательный результат равен 8+16=24; 24 — окончательный результат.

Исходный адрес: https://www.cnblogs.com/lykbk/archive/2013/04/02/krtmbhrkhoirtj9468945.html