Assigning a pointer of a record to an array of char in Delphi - come again?
I recently started working on a Delphi project and found very strange piece of code.
// Type declarations
type
TDataSet = record
VolumeLevel : char;
DeviceMasks : char;
DeviceList: array [1..MAX] of array [1..8] of char;
DisplayList: array [1..MAX] of array [1..8] of char;
end;
type
开发者_JS百科 TSerialPacket = record
Preamble: array[1..4] of byte;
PacketType: byte;
PacketLen: byte;
Data: array of char;
Checksum: byte;
end;
...
// Private fields
Packet : TSerialPacket;
DataSet : TDataSet;
...
// Actual procedure
SetLength(Packet.Data, sizeof(DataSet));
Packet.Data := @DataSet;
I haven't used Delphi very much so this code seems incomprehensible to me. Compiler thinks this is alright and I can run the code. I ran it with debugger but the value of Packet.Data does not seem to change. Can anyone tell me what this does? It seems very strange to assign a pointer of a custom record to an array of chars.
Also, for some reason the SetLength triggers an error: "Project Foo.exe raised exception class EAccessViolation with message 'Access violation at address 00403860 in module 'Foo.exe'. Read of address 00000000.". During both the working and the crashing runs value of Packet.Data is () and sizeof DataSet is 260. I haven't been able to pinpoint what exactly changes. As far as I know, SetLength should not depend on any other variables than Packet.Data and DataSet.
(I use Delphi XE on Windows 7.)
I guess the last line (
Packet.Data := @DataSet;
) should rather be
Move(DataSet, Packet.Data[0], SizeOf(DataSet));
I think I know what is going wrong with your code...
Like already stated, this is pretty bad:
SetLength(Packet.Data, sizeof(DataSet));
Packet.Data := @DataSet;
I'D assume your code will crash on SetLength only the 2nd time you run through it. What happens is
Packet.Data := @DataSet;
Here, the Array of Char pointer is replaced by the address of the Dataset variable. The Array of Char that was created by "Setlength" is then "freed".
When you get to SetLength for a second time, what the compiler thinks is a pointer to an Array of Char is in fact a pointer to a TDataset. It is similar to calling
SetLength(@Dataset, SizeOf(Dataset));
(Except that the compiler won't allow that one)
I hope that helps at finding any additional problems your are experiencing.
精彩评论