#c #memory-alignment
#c #выравнивание памяти
Вопрос:
Согласно Википедии, структура, содержащая один байт и четырехбайтовое целое число в таком порядке, потребует трех дополнительных байтов заполнения, поскольку четырехбайтовое целое число должно быть выровнено на 4 байта.
- Структура, содержащая четырехбайтовое целое число и один байт в таком порядке, не потребует дополнительных байтов заполнения, поскольку один байт будет выровнен по 1 байту?
- Размер первой структуры будет равен 8, но размер второй структуры будет равен 5?
- Как насчет другого четырехбайтового целого числа, выделенного в памяти после второй структуры выше? Будет ли он выделен после разрыва в 3 байта, чтобы он соответствовал выравниванию в 4 байта?
[обновление из комментария:]
Я забыл упомянуть, что мой пример используется в 32-разрядной системе.
[ОБНОВИТЬ]
Я только что узнал, что инструкции пакета, добавленные в начале и в конце структуры, применяются только к элементам структуры и не распространяются на другие структуры. Это означает, что если у вас есть структура структур, вы должны упаковывать их по отдельности, а не только родительскую структуру.
Комментарии:
1. Просто чтобы немного запутать вас, вы можете поручить большинству компиляторов минимизировать или удалить заполнение настолько хорошо, насколько это возможно.
2. Вы имеете в виду указание компиляторам «упаковывать» элементы структуры до определенного уровня выравнивания, например, «pack (2)»?
3. это именно то, о чем я говорю 🙂
4. экземпляры struct всегда используют размер, кратный размеру адреса компьютера, и всегда начинаются с границы адреса размера адреса компьютера. ЕСЛИ пакет pragma не используется перед первым экземпляром struct . Это также означает, что поля внутри структуры будут содержать заполнение, поэтому тип поля будет выровнен (т.Е. int будет выровнен по 4-байтовой границе адреса)
5. Я только что узнал, что инструкции пакета, добавленные в начале и в конце структуры, применяются только к элементам структуры и не распространяются на другие структуры. Это означает, что если у вас есть структура структур, вы должны упаковывать их по отдельности, а не только родительскую структуру.
Ответ №1:
- Может быть, а может и нет. Возможно, вы работаете в архитектуре, которая любит заполнение до 8-байтовых границ.
- Возможно. Никогда не предполагайте одинаковое, предсказуемое двоичное представление структуры C в разных компиляторах. Или даже через разные параметры в одном компиляторе.
- Возможно. Вероятно, в архитектуре примера. Но на самом деле разрыв может быть больше, если библиотеки компилятора имеют тенденцию выделять большие куски.
Комментарии:
1. Я забыл упомянуть, что мой пример используется в 32-разрядной системе.
2. Это все еще очень зависит от компилятора. И общий ответ: «Возможно, но исправьте тестовое приложение и распечатайте
sizeof()
, чтобы увидеть эту структуру».3. Теперь, когда я указал архитектуру, ваш ответ немного сбивает с толку. Если не указано упаковать данные с определенным выравниванием в 32-разрядной архитектуре, почему 2 компилятора будут вести себя по-разному?
4. Потому что они могут. Они могут заполнить символ до 1024 КБ, если захотят (не то, что они хотели бы). Стандарт не требует выравнивания структуры. Компилятор может способствовать экономии пространства; другой может способствовать скорости доступа и выравнивать все по 32-разрядным границам; другой может быть настроен на потребности своих библиотек malloc. Вы можете предполагать весь день, или вы можете проверить, что ваш компилятор делает в вашей среде.
Ответ №2:
При выравнивании и упаковке данных не учитывается, что существует как минимум 2 аспекта выравнивания данных.
Производительность: некоторые выравнивания типов, например, 4-байтовые int
, часто выполняются быстрее при выравнивании по соответствующей (четырехбайтовой) адресной границе. Это часто используется компилятором по умолчанию. Иногда возможны другие выравнивания с более низкой производительностью. Параметры пакета, зависящие от компилятора, могут использовать эту менее оптимальную компоновку скорости для достижения меньшего заполнения.
Требуется: требуется определенное выравнивание типов, например, 2-байтовое целое число может вызвать сбой шины на нечетном адресе. Параметры пакета, специфичные для компилятора, не будут нарушать это. Упаковка может уменьшить заполнение, но некоторое заполнение может остаться.
Чтобы ответить на вопросы OP:
все «возможно». Это зависит от компилятора с учетом его опций и целевого оборудования.