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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With