让我们来分解一下:
“对齐规则”“要求每个原始数据元素的地址是元素大小的偶数倍”。我们谈论对齐规则并不是很有趣;我们已经知道了。
“要求每个原始数据元素的地址”是“元素大小的偶数倍”。现在我们已经取得进展了。我们有一个要求和范围:
Requirement: The address is an even multiple of the element's size.
Scope: Every primitive data element.
因此,每次我们定位一个元素时,我们都必须施加要求。
让我们尝试在内存中定位一个元素。我们首先要定位的是short
贴上标签s
。由于 Short 占用 2 个字节的内存,并且我们必须使其地址成为该大小的倍数,因此该地址必须是 2 的倍数。我们将该地址称为 N。
So, s
占用空间来自N
up to N + 2
. (NOTE:对于所有这些范围,包括第一个端点,但不包括最后一个端点。这是计算机科学中描述整数范围的常用方法;在大多数情况下,这是迄今为止最有用且最不容易出错的方法。相信我。)
我们继续彼此的领域。
c
占用一个字节,从N + 2
to N + 3
.
我们在N + 3
,但我们无法开始t
在那里,因为N + 3
是奇数(因为N
甚至)。所以我们必须跳过一个字节。因此t
范围从N + 4
to N + 6
.
继续这种逻辑,我们最终得到d
from N + 6
to N + 7
; r
from N + 8
to N + 16
; i
from N + 16
to N + 20
. (NOTE仅当我们将 N 限制为 8 的倍数时,这才有效,或者r
将不对齐。还行吧;当我们为数组分配内存时,我们可以根据需要对齐它的开头 - 我们只需要保持该点之后的数据顺序一致即可。)
所以我们需要at least该结构有 20 个字节。 (这是半开范围的优点之一:端点之间的差异等于大小。如果我们在范围中包含或排除两个端点,则必须进行 +1 或 -1 修正。)
现在假设我们尝试将数组布局为 10 个连续的 20 字节块。这行得通吗?不;假设元素 0 位于地址 256(8 的倍数)。现在r
元素 1 中的 不会对齐,因为它将从 256 + 20 + 8 开始,不能被 8 整除。这是不允许的。
所以我们现在怎么办?我们不能只在前面插入额外的 4 个字节r
在元素 1 中,因为数组的每个元素都必须具有相同的布局(更不用说大小)。但有一个简单的解决方案:我们在end of each元素。现在,只要数组从 8 的倍数开始,每个元素也将从 8 的倍数开始(这反过来又保持r
对齐),因为现在大小是 8 的倍数。
我们得出结论,结构需要 24 个字节,因此数组需要 24 * 10 = 240 个字节。