Reputation: 1001
I have a next code:
type THead = packed record
znmpc: byte;
znmpcch: array [0..1] of char;
znc, zneispr, zkpd, zkps, nd: byte;
zb9, zb10, zb11, zb12, zb13, zb14, zb15: byte;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
db: ^THead;
a: array [0..9] of byte;
begin
a[7] := 9;
db := @a;
ShowMessage(IntToStr(db.nd));
end;
Is this code safe? I'm worried about next thing: size of struct more than size of buffer, and i have a fear about it. The value of members of struct after nd has no meaning for me. I want to know can this code throw an exception in certain circumstances, and if so in what?
Upvotes: 3
Views: 763
Reputation: 1795
I guess reading db.nd is fine. You will access somewhere in stack which doesn't belong to you. But writing something to this variable can cause catastrophic failure, we can not know.
Also, If you exceed your boundary too much, you can get access violation for reading too:
procedure TForm2.Button1Click(Sender: TObject);
var
db: THead;
p: PByte;
begin
db.nd := 9;
p := @db;
ShowMessage(IntToStr(p[7])); // shows 9
ShowMessage(IntToStr(p[700])); // shows 182 for me?
ShowMessage(IntToStr(p[70000])); // shows 0
ShowMessage(IntToStr(p[700000])); // access violation!
end;
It is safer using unions:
type
THead = packed record
znmpc: byte;
znmpcch: array [0..1] of AnsiChar;
znc, zneispr, zkpd, zkps, nd: byte;
zb9, zb10, zb11, zb12, zb13, zb14, zb15: byte;
end;
THeaderUnion = packed record
case Integer of
0: (Head: THead);
1: (ByteArray: Array[0.. sizeof(THead)-1] of Byte);
end;
procedure TForm1.Button1Click(Sender: TObject);
Var
db: THeaderUnion;
begin
db.ByteArray[7] := 9;
ShowMessage(IntToStr(db.Head.nd));
end;
Upvotes: 2
Reputation: 108929
I'd guess it is perfectly safe if you handle it carefully. But you need to be certain that you do not forget that you may not access zb11..zb15
. In addition, recall that a char
is 1 byte prior to Delphi 2009, and 2 bytes in Delphi 2009 and later versions. Also, maybe it is worth to make the record packed
(don't think you need that in this case, but it is never wrong to be pedantically explicit)? Finally, of course you have to be careful so that the array doesn't go out of scope!
Upvotes: 6