为什么记录的大小不等于其字段大小的总和?

时间:2012-03-21 10:54:05

标签: delphi sizeof

我有下一个代码:

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?

2 个答案:

答案 0 :(得分:15)

这是由于记录对齐而添加了填充。 TRecord3的对齐方式为4,因为它包含single个值。因此,填充将添加到记录的末尾,以使大小成为4的精确倍数。这就是为什么大小为136而不是您期望的134的值。

您可以将记录声明为packed,或者等效地将对齐编译器选项设置为$ALIGN 1。对齐1时,记录和SizeOf(TRecord3)=134不会添加填充。但是,我强烈建议你不要这样做。使用自然对齐可以为记录提供最有效的内存访问。例如,处理器加载未对齐值比加载对齐值更昂贵。对于singleinteger,自然对齐位于4字节边界上。对于double,自然对齐在8字节边界上,依此类推。如果需要与使用打包记录的另一个库进行二进制兼容,则应使用打包记录。

答案 1 :(得分:4)

这是由于对齐。记录中的字段在4个字节或8个字节(或仅在记录中使用字节时的字节)上对齐,使得在数组中所有字段的记录将保持对齐。如果您希望公式起作用,则应使用“打包记录”。请注意,字段可能未对齐,可能会妨碍性能。