Понимание заполнения структуры в C

Под концепцией выравнивания данных я понимаю, что int и float должны храниться по адресу, который делится на 4 (начальный адрес байта). В соответствии с ним размер приведенной ниже структуры равен 12

 typedef struct{
    char A;
    int B;
    float C;
}y;

Я не сомневаюсь в понимании размера указанной выше структуры. Теперь я сомневаюсь в размере нижней структуры.

typedef struct {
    double A;
    char B;
    char C;
}x;

размер x равен 16. в чем я сомневаюсь, так это то, что два используемых символа могут быть выделены в 2 байта, так что вся структура использует 10 байтов данных, а оставшиеся 2 байта можно использовать для выделения другому короткому int, когда он был объявлен Правильно?

Но компилятор использует 16 байтов данных и заполняет остальные 6 ячеек. Я не могу понять, почему он тратит еще 6 ячеек, если он может использовать их для других переменных, когда они объявлены ?. Может ли кто-нибудь помочь мне понять вышеупомянутую концепцию? (Я предполагаю размер int, float и double как 4,4,8 байта соответственно.)


person mani kanta    schedule 11.07.2018    source источник


Ответы (1)


В случае x он содержит double, который (в вашем случае) имеет размер 8. Это означает, что структура в целом должна быть кратной этому размеру, чтобы массив x был правильно выровнен.

Поскольку массивы размещаются непрерывно, каждый член массива располагается в памяти сразу после предыдущего. Если бы x имел размер 10, то для второго элемента массива со смещением 10 был бы член A. Для правильного выравнивания каждый член массива должен начинаться с размера, кратного размеру самого большого элемента. Таким образом, структура содержит отступы в конце для достижения этой цели.

person dbush    schedule 11.07.2018
comment
@fvu Не то чтобы это требовало большего выравнивания. Ему просто нужно дополнительное заполнение, чтобы все элементы массива были выровнены. - person dbush; 11.07.2018
comment
Не могли бы вы объяснить, как правильно выровняли? Я не вижу причин, по которым удвоение не может начинаться на границах, отличных от 8 байтов. Расчет адреса составляет всего &x+(sizeof(x)*index)+offset(member) в байтах. - person Paul Ogilvie; 11.07.2018
comment
@PaulOgilvie Хотя, строго говоря, выравнивание определяется реализацией, в общем случае ожидается, что любой непроизводный тип (char, int, double, указатели и т. Д.) Будет находиться по адресу памяти, кратному размеру объекта. Некоторые процессоры генерируют ошибку, если выполняется доступ к невыровненной памяти. - person dbush; 11.07.2018
comment
Это архитектура ЦП или архитектура памяти / шины? (Пока память размещает данные на выводах данных ЦП, ЦП не должно заботиться.) В любом случае, я понимаю, что заполнение, по-видимому, является функцией архитектуры, для которой компилятор генерирует код. - person Paul Ogilvie; 11.07.2018
comment
Хммм ... Я забыл о кеш-памяти на микросхеме ЦП, которая является частью архитектуры памяти. Таким образом, ЦП диктует архитектуру памяти и, таким образом, диктует требования к согласованию. Проголосуйте за ваш ответ. - person Paul Ogilvie; 11.07.2018