开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜