Basically my issue is that I have to use very often this kind of structure:
type myrecord1=record
aa:array of string;
bb:array of array of integer;
cc:array of boolean;
dd:string;
end;
type myArray=array of myrecord1;
....
....
var
a:myArray;
begin
setLength(a,0);
while mycondition do
begin
setLength(A,length(A)+1);
A[length(A)-1].dd:='Test';
end;
end;
At the moment every time I have to do something like this:
setLength(A,length(A)+1);
setLength(A[length(A)-1].aa,0); //Boring and dangerous line
setLength(A[length(A)-1].bb,0); //Boring and dangerous line
setLength(A[length(A)-1].cc,0); //Boring and dangerous line
A[length(A)-1].dd:='Test';
The "Boring and dangerous lines" are easy sources of bugs.
What I would like to have is that when I do setLength(A,length(A)+1) , every subArray length is set to 0 and not to a random value.
I think that with your code I should obtain this, is it ?
You must be doing something wrong. I suspect, that you have heap corruption somewhere in your code.
My code is:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TMyRecord = record
A:array of Integer;
B:array of String;
C:array of Boolean;
end;
TMyArray = array of TMyRecord;
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
procedure FillArray;
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FillArray;
var V:TMyArray;
I, J:Integer;
begin
Memo1.Lines.Add('Fill start');
for I := 0 to 9 do begin
SetLength(V, Length(V) + 1);
with V[Length(V) - 1] do begin
Memo1.Lines.Add(
IntToStr(Length(A)) + ' ' +
IntToStr(Length(B)) + ' ' +
IntToStr(Length(C))
);
SetLength(A, 10);
SetLength(B, 10);
SetLength(C, 10);
for J := 0 to 9 do begin
A[J] := Random(10) + 1;
B[J] := IntToStr(A[J]);
C[J] := (A[J] and 1) = 1;
end;
end;
end;
Memo1.Lines.Add('Fill end');
Memo1.Lines.Add('Test begin');
for I := 0 to Length(V) - 1 do begin
with V[I] do begin
Memo1.Lines.Add(
IntToStr(Length(A)) + ' ' +
IntToStr(Length(B)) + ' ' +
IntToStr(Length(C))
);
end;
end;
Memo1.Lines.Add('Test end');
end;
procedure TForm1.FormCreate(Sender: TObject);
var I:Integer;
begin
for I := 0 to 9 do begin
Memo1.Lines.Add('Test #' + IntToStr(I + 1));
FillArray;
end;
end;
end.
Working, as intended. Initialized by 0 at beginning of test and everything is 10 at the end. No errors.
Test #1
Fill start
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Fill end
Test begin
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
Test end
Test #2
Fill start
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Fill end
Test begin
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
Test end
Test #3
Fill start
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Fill end
Test begin
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
Test end
Test #4
Fill start
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Fill end
Test begin
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
Test end
Test #5
Fill start
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Fill end
Test begin
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
Test end
Test #6
Fill start
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Fill end
Test begin
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
Test end
Test #7
Fill start
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Fill end
Test begin
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
Test end
Test #8
Fill start
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Fill end
Test begin
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
Test end
Test #9
Fill start
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Fill end
Test begin
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
Test end
Test #10
Fill start
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Fill end
Test begin
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
10 10 10
Test end
OK, maybe that has been some change in dyn arrays managment between 1.6(or earlier) and 1.8 lazarus ?
Sometime I had problems about code not everytime working at the same. It could happened that on a PC the code was working and on another not. But it was the same code working on the same data.
Initialiazing dynamic arrays the problems disappeared.
Since then I always initialize my dynamic arrays and no more problem.
Unfortunately at the moment I haven't any code to provide as example. I am going to try to provide it.
I prefer dyn arrays over classes because there is minor risks about memory leaks. Specially in try... except blocks.