3 回答

TA贡献883条经验 获得超454个赞
每种类型都有一个叫做“对齐值”的属性。这个属性相当于描述“在内存中其能够分配的起始地址和前一一个此类型能够分配的起始地址的间距”。
啊,好吧,我的文字表达能力比较差,上述说法我自己看着都觉得累,其实通俗地说就是限制了“能在内存中哪些位置放这个类型的对象”。
我还是举些例子吧,我们在假想的一小段内存中进行描述,这段内存的起始地址被当作 0 地址:
假定 int 类型本身占 4 字节,对齐值也是 4。那么如果想在这段内存中放一个 int 变量,能放在哪里呢?
起始的 0 字节处当然可以放。但如果我不从这段内存起始处放,能不能从第 2 字节处放一个 int 呢? 答案是不可以!
因为 int 的对齐值是 4。内存 0 字节之后,只能间隔 4 字节再放一个 int 对象,所以只能在这段内存的 4 字节处放一个 int。注意:这并不是因为 0 到 3 字节被前一个 int 占用了!即便这段内存中只放一个 int,前面 0 到 3 字节都是空的,也不能在 1、2、3 字节处放置 int ——两个合法的放置 int 的起始地址必须间隔 4。
也就是只能在这段内存的 0、4、8、12 ....字节处分配 int 对象。
char 类型本身占用 1 字节(这点不用假设了,C标准规定如此),对齐值也是 1 。那么你可以知道,这段内存的任何一个字节处都可以合法地放置一个 char 对象。
我希望你看懂了我的这些罗嗦解释。
还有,就像你知道 C 语言是很灵活的,其实 C 标准并没有规定每种类型具体占用内存的大小和其对齐值,不同平台可能有自己的规定。C 标准只是规定了对齐值必须是 2 的整数次幂(从 C11 标准开始,你可以用 _Alignof 运算符来获得类型的对齐值)
union 的所有成员的起始地址都一样,所以基本上不用考虑对齐的问题。
struct 的不同成员是依次放置于内存中的,每个成员在内存中的位置都必须满足其类型对齐值的要求! 而整个 struct 的对齐值一般是其成员对齐值中最大的一个(不过此题不涉及这点)。
正如我前面提到 C 标准没有具体规定类型的对齐值。那么严格地说,这道题出得也不严谨,它应该说明这些类型的对齐值再让学生做计算的。既然它没说,我就用常见的对齐值来解释下题目中的 struct:
int 占 4 字节,对齐值为 4。所以 struct 中前 4 个字节就是这个 num,这是很显然的。
char 占 1 字节,对齐值为 1。数组中元素是紧挨着放置的,所以 name 数组占 10 字节。
这样 struct 前 14 个字节就是 num 和 name 占用的。
float 占 4 字节,对齐值为 4。那第三个成员 score 就不能从第 15 字节起了。它必须放在 4 的倍数的位置上,所以第 15、16 字节要被空出来,从第 17 字节处放置 score。score 占用第 17、18、19、20 字节。
那么整个 struct 就占用 20 字节。
- 3 回答
- 2 关注
- 1843 浏览
添加回答
举报