выравнивание памяти в структуре - размер выравнивания равен наибольшему размеру элемента

0

Я хотел бы знать, почему мы должны взять для размера выравнивания структуры размер выравнивания, равный наибольшему размеру члена в структуре.

Пример:

struct MixedData
{
    char Data1;
    short Data2;
    int Data3;
    char Data4;
}; 

Если мы берем наибольший член (int Data3), выравнивание равно 4 байтам, так что нам нужно сделать:

struct MixedData  /* After compilation in 32-bit x86 machine */
{
    char Data1; /* 1 byte */
    char Padding1[1]; /* 1 byte for the following 'short' to be aligned on a 2 byte boundary 
                         assuming that the address where structure begins is an even number */
    short Data2; /* 2 bytes */
    int Data3;  /* 4 bytes - largest structure member */
    char Data4; /* 1 byte */
    char Padding2[3]; /* 3 bytes to make total size of the structure 12 bytes */
};

Но почему у меня нет, после char Data1, char Padding1[3] поэтому short Data2 начинается с adress(Data1) + 4 вместо char Data1[1]?

И, с той же логикой, почему у меня нет short Padding3[1] после short Data2?

Другой вопрос: если я на 64-битном процессоре, я должен использовать выравнивание по 8 байт, поэтому я должен установить следующее:

struct MixedData  /* After compilation in 64-bit x86_64 machine */
{
    char Data1; /* 1 byte */
    char Padding1[7]; /* 7 bytes */
    int Data3;  
    int Padding2[1]/* 4 bytes */
    char Data4; 
    char Padding3[7]; /* 7 bytes to make total size of the structure 24 bytes */
};

?

поэтому общий размер 24 байта кратен 8 байтам?

  • 3
    Заполнение обычно выполняется для «естественного» выравнивания поля. То есть поле dword выровнено по dword, поле word выровнено по словам и так далее. Не существует наказания за доступ, скажем, к полям размером в слово, которые не выровнены по словам (но выровнены по словам).
  • 0
    @ 500-InternalServerError: это должно было быть опубликовано как ответ вместо комментария.
Теги:
memory-alignment

1 ответ

0
Лучший ответ

OVERALL-выравнивание структуры должно соответствовать элементу с наибольшим требованием выравнивания. Это необходимо для обеспечения того, чтобы, например, массив структур всегда выравнивался. Если у вас этого нет, размер struct { int x; char c; }; struct { int x; char c; }; будет иметь первый элемент, выровненный, но следующие три будут иметь x unaligned.

Часто можно убедить компилятор генерировать "упакованную" структуру данных (без добавления выравнивания) и использовать ее для получения упакованного массива, но это плохая идея использовать это во всех, кроме очень особых случаях, потому что в лучшем случае это медленнее, в худшем случае это приводит к остановке выполнения из-за "неувязки доступа" в процессоре.

Если размер int равен четырем байтам [это для всех компиляторов, о которых я знаю - long - это 4 или 8 байт, зависит от компилятора), как на 32-, так и на 64-битной (по крайней мере, x86) будет выровнять по 4 байта.

Если вы хотите иметь 7-байтовый "пробел" в структуре, это будет работать:

struct X { 
   char c;
   uint64_t x;
}; 

что, конечно же, имело бы:

struct X { 
   char c;
   char padding[7]; 
   uint64_t x;
};

Ещё вопросы

Сообщество Overcoder
Наверх
Меню