我有下一个代码:
type TRecord1 = record
myarr: array [0..31] of single:
end;
type TRecord2 = record
b1, b2, b3, b4, b5, b6: byte;
end;
type TRecord3 = record
myarr: array [0..31] of single:
b1, b2, b3, b4, b5, b6: byte;
end;
procedure TForm1.FormCreate(Sender: Tobject);
begin
ShowMessage(IntToStr(SizeOf(TRecord1))+'+'+IntToStr(SizeOf(TRecord2))+
'='+IntToStr(SizeOf(TRecord3)));
end;
该程序显示以下消息:
128+6=136
为什么SizeOf(TRecord3)
等于136而不是134?
答案 0 :(得分:15)
这是由于记录对齐而添加了填充。 TRecord3
的对齐方式为4,因为它包含single
个值。因此,填充将添加到记录的末尾,以使大小成为4的精确倍数。这就是为什么大小为136而不是您期望的134的值。
您可以将记录声明为packed
,或者等效地将对齐编译器选项设置为$ALIGN 1
。对齐1
时,记录和SizeOf(TRecord3)=134
不会添加填充。但是,我强烈建议你不要这样做。使用自然对齐可以为记录提供最有效的内存访问。例如,处理器加载未对齐值比加载对齐值更昂贵。对于single
或integer
,自然对齐位于4字节边界上。对于double
,自然对齐在8字节边界上,依此类推。如果需要与使用打包记录的另一个库进行二进制兼容,则应使用打包记录。
答案 1 :(得分:4)
这是由于对齐。记录中的字段在4个字节或8个字节(或仅在记录中使用字节时的字节)上对齐,使得在数组中所有字段的记录将保持对齐。如果您希望公式起作用,则应使用“打包记录”。请注意,字段可能未对齐,可能会妨碍性能。