在Delphi中将记录的指针分配给char数组-再来吗? [英] Assigning a pointer of a record to an array of char in Delphi - come again?

查看:87
本文介绍了在Delphi中将记录的指针分配给char数组-再来吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始从事Delphi项目,并发现了一段非常奇怪的代码。

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
    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的值似乎没有变化。谁能告诉我这是什么?将自定义记录的指针分配给一个字符数组似乎很奇怪。

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.

此外,由于某些原因,SetLength会触发错误:异常类EAccessViolation,消息为 Foo.exe中的地址00403860的访问冲突。读取了地址00000000。。在正常运行和崩溃运行期间,Packet.Data的值为(),Dataof的size为260。我无法确定确切的变化。据我所知,SetLength不应依赖于Packet.Data和DataSet之外的任何其他变量。

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.

(我在Windows 7上使用Delphi XE。)

(I use Delphi XE on Windows 7.)

推荐答案

我想我知道您的代码出了什么问题...

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; 

我假设您的代码只会在您第二遍运行SetLength时崩溃。
会发生什么事

I'D assume your code will crash on SetLength only the 2nd time you run through it. What happens is

Packet.Data := @DataSet;

在这里,将Char指针数组替换为Dataset变量的地址。然后,释放由 Setlength创建的Char数组。

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".

第二次访问SetLength时,编译器认为是指向Char数组实际上是指向TDataset的指针。类似于调用

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.

这篇关于在Delphi中将记录的指针分配给char数组-再来吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆