Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't the size of a record equal to the sum of the sizes of its fields?

Tags:

sizeof

delphi

I have next code:

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;

The program shows the following message:

128+6=136

Why is SizeOf(TRecord3) equal to 136 rather than 134?

like image 558
Xaver Avatar asked Mar 21 '12 10:03

Xaver


2 Answers

This is due to padding added because of record alignment. TRecord3 has alignment of 4 since it contains single values. And so padding is added to the end of the record to make the size an exact multiple of 4. That's why the size is 136 rather than the value of 134 that you were expecting.

You can declare your record to be packed, or, equivalently, set the alignment compiler option to $ALIGN 1. With an alignment of 1 there will be no padding added to the record and SizeOf(TRecord3)=134. However, I strongly recommend you do not do this. Using the natural alignment results in the most efficient memory access for records. For example, it is more expensive for the processor to load a misaligned value than to load an aligned value. For a single or an integer, the natural alignment is on a 4 byte bounday. For a double the natural alignment is on an 8 byte boundary and so on. You should use packed records if you need binary compatibility with another library that uses packed records.

like image 98
David Heffernan Avatar answered Nov 02 '22 05:11

David Heffernan


This is due to alignment. The fields in the record are aligned on 4 bytes or 8 bytes (or bytes when only bytes are used in the record.) in such a manner that the record when in an array all fields will keep on being aligned. If you want the formula to work you should use a 'packed record'. Please note that the fields might be unaligned and could hamper performance.

like image 41
Ritsaert Hornstra Avatar answered Nov 02 '22 04:11

Ritsaert Hornstra