我最近开始研究Delphi项目,发现了一段非常奇怪的代码 .
// 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
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;
我没有非常使用Delphi,所以这段代码对我来说似乎难以理解 . 编译器认为这没关系,我可以运行代码 . 我用调试器运行它,但Packet.Data的值似乎没有改变 . 谁能告诉我这是做什么的?将自定义记录的指针分配给字符数组似乎很奇怪 .
此外,由于某种原因,SetLength触发错误:“Project Foo.exe引发异常类EAccessViolation,并在模块'Foo.exe'中的地址00403860处发出访问冲突信息 . 读取地址00000000 . ” . 在工作和崩溃运行期间,Packet.Data的值为(),而Dataof的sizeof为260.我无法确定究竟有什么变化 . 据我所知,SetLength不应该依赖于Packet.Data和DataSet之外的任何其他变量 .
(我在Windows 7上使用Delphi XE . )
2 回答
我想我知道你的代码出了什么问题......
就像已经说过的那样,这非常糟糕:
我假设您的代码仅在第二次运行时才会在SetLength上崩溃 . 会发生什么
这里,Char数组的指针被数据集变量的地址替换 . 然后“释放”由“Setlength”创建的Char数组 .
当你第二次进入SetLength时,编译器认为指向Char数组的指针实际上是指向TDataset的指针 . 它类似于通话
(除了编译器不允许那个)
我希望这有助于找到您遇到的任何其他问题 .
我猜最后一行(
)应该是