【发布时间】:2011-12-17 12:05:14
【问题描述】:
下面是一段非常简单的代码,它模仿了我拥有的一些代码中的类结构(表单只包含一个附加到单击事件的按钮)。我正在使用 Delphi XE 和 XE II,并且在销毁此类所基于的生产代码中的对象时看到严重的崩溃。只有当我允许在 Clear() 方法中初始化 TMyClass 中的数组项的成员时,才会发生这些崩溃。
不幸的是,到目前为止,此示例代码中的崩溃是不可重复的,但它确实模仿了一些非常奇怪的行为,我怀疑这可能是导致问题的原因。
如果我在 TMyClass.Clear 函数中放置一个断点并查看类的 InstanceSize 成员报告 1288。这很奇怪,因为仅数组成员的大小实际上是 12kb。我可以将提供的类型从 TRecord2 更改为 Integer,并且得到相同的 InstanceSize 结果。如果我从类中完全删除数组,我会得到一个大约 264 字节的实例大小,这对于只包含一个 128 字节记录实例的类来说似乎超过了顶部。这表明编译器已为 TMyClass 中的 V(TT 类型)成员的数组存储分配了 1024 个字节。
当我将 12kb 的数据写入编译器认为大小为 1kb 的对象时,我怀疑奇怪的实例大小会导致坏事发生。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TRecord = record A : Array[1..128] of byte; end;
TRecord2 = packed record S : Single; T : TDateTime; end;
TBase = class(TObject)
public
R : TRecord;
end;
TBase2<T> = class(TBase)
public
type
TT = packed array [0..31, 0..31] of T;
var
V : TT;
R2 : TRecord;
end;
TMyClass = class(TBase2<TRecord2>)
public
procedure Clear;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
O : TMyClass;
begin
O := TMyClass.Create;
O.Clear;
O.Free;
end;
{ TMyClass }
procedure TMyClass.Clear;
var
i, j : integer;
begin
for i := 0 to 31 do
for j := 0 to 31 do
begin
V[I, J].S := 0;
V[I, J].T := 0;
end;
end;
end.
【问题讨论】:
-
我有点不知所措,但也许这些信息会有所帮助。大多数内置类都有 Clear 方法,当对象被销毁时会自动调用 Clear 方法。
标签: delphi generics delphi-xe delphi-xe2