Давайте разберемся с этим:
"правила выравнивания", которые "требуют, чтобы адрес каждого примитивного элемента данных был кратным размеру элемента".Не очень интересно, что мы говорим о правилах выравнивания;мы уже знали, что.
«требуют, чтобы адрес» каждого «простого элемента данных» был «четным кратным размера элемента».Теперь мы куда-то добираемся.У нас есть требование и область действия:
Requirement: The address is an even multiple of the element's size.
Scope: Every primitive data element.
Итак, каждый раз, когда мы позиционируем элемент, мы должны налагать требование.
Давайте попробуем поместить элемент в память.Первое, что мы разместим, это short
, помеченный s
.Поскольку short занимает 2 байта памяти, и мы должны сделать его адрес кратным этому размеру, адрес должен быть кратным 2. Давайте назовем этот адрес N.
Итак, s
занимаетпространство от N
до N + 2
.( ПРИМЕЧАНИЕ : для всех этих диапазонов первая конечная точка включена, а последняя - нет. Это обычный способ описания диапазонов целых чисел в информатике; в большинстве случаев это, безусловно,самый полезный и наименее подверженный ошибкам способ сделать это. Поверьте мне.)
Мы продолжаем работу друг с другом.
c
занимает один байт, от N + 2
до N + 3
.
Мы находимся на N + 3
, но мы не можем начать там t
, потому что N + 3
нечетно (поскольку N
четно).Поэтому мы должны пропустить байт.Таким образом, t
варьируется от N + 4
до N + 6
.
Продолжая эту логику, мы получим d
от N + 6
до N + 7
;r
от N + 8
до N + 16
;i
от N + 16
до N + 20
.( ПРИМЕЧАНИЕ , что это работает, только если мы ограничим N кратным 8, или r
будет не выровнено. Это нормально; когда мы выделяем память для массива, мы можем выровнять началокак бы мы этого ни хотели - мы просто должны быть последовательными в отношении последовательности данных после этой точки.)
Поэтому нам нужно не менее 20 байтов для этой структуры.(Это одно из преимуществ полуоткрытых диапазонов: разница между конечными точками равна размеру. Если бы мы включили или исключили обе конечные точки из диапазона, мы должны были бы сделать поправку +1 или -1.)
Теперь предположим, что мы пытаемся разложить массив как десять последовательных кусков по 20 байтов.Будет ли это работать?Нет;скажем, что элемент 0 находится по адресу 256 (кратно 8).Теперь r
в элементе 1 будет не выровнен, потому что он начнется с 256 + 20 + 8, который не делится на 8. Это не разрешено.
Так что же нам теперь делать?Мы не можем просто вставить дополнительные 4 байта перед r
в элементе 1, потому что каждый элемент массива должен иметь одинаковую разметку (не говоря уже о размере).Но есть простое решение: мы вставляем 4 байта дополнительного дополнения в end из каждого элемента.Теперь, пока массив начинается с кратного 8, каждый элемент также будет начинаться с кратного 8 (что, в свою очередь, сохраняет r
выровненным), потому что размер теперь кратен 8.
Мы заключаем, что нам нужно 24 байта для структуры, и, таким образом, 24 * 10 = 240 байтов для массива.