Below is a very simple bit of code that mimics the structure of a class in some code that I have (the form contains only one button attached to a click event). I use Delphi XE and XE II and I see unpleasant crashes when destroying objects in my production code on which this class is based. These crashes only occur if I allow the members of the array element in TMyClass to initialize the Clear () method.
Unfortunately, the crash is not repeated so far in this code example, but it imitates some very strange behavior with the size of the instance, which, I suspect, might be causing the problem.
If I put a breakpoint in the TMyClass.Clear function and look at the InstanceSize member of 1288 class reports. This is strange, since the size of the array element is actually 12kb. I can change the type provided from TRecord2 to Integer and get the same InstanceSize result. If I completely remove the array from the class, I get an instance of ~ 264 bytes in size, which appears above, for a class that contains only one record instance of 128 bytes. This indicates that the compiler allocated 1024 bytes to the array storage for member V (type TT) in TMyClass.
I suspect that the weird instance size causes bad things when I write 12kb of data to an object, which, according to the compiler, is 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.
generics delphi delphi-xe delphi-xe2
Raymond wilson
source share