zur
Unit uReadWrite_2D_Arrays:
Die mit der Verwendung des Parameters T2DStringArray überladenen Prozeduren Save2DArray() and Load2DArray() enthalten einen äußerst fatalen Fehler:
In den Anweisungen dieser beiden Prozeduren writer.Write() bzw. reader.Read() wird das Element [i,x] des Array A (also A[i,x]) ja nicht als String, sondern als Puffer übergeben. Daher muss zwingend als Start des übergebenen Puffers die erste Position des Stringelements
A[i,x][1] gesetzt werden (nicht einfach nur A[i,x]).
Die beiden betroffenen Prozeduren müssen richtig wie folgt codiert sein:
Code:
procedure Save2DArray(const A: T2DStringArray; S: TStream); overload;
var
writer: TWriter;
i,x: Integer;
begin
Assert(Assigned(S));
writer := TWriter.Create(S, 8096);
try
writer.WriteInteger(Length(A));
for i := 0 to Length(A) - 1 do
begin
writer.WriteInteger(Length(A[i]));
for x := 0 to Length(A[i]) - 1 do
begin
Writer.WriteInteger(Length(A[i,x]));
writer.Write(A[i, x][1], Length(A[i,x])); // <-- !
end;
end; { For }
finally
writer.Free;
end; { Finally }
end;
Code:
procedure Load2DArray(var A: T2DStringArray; S: TStream); overload;
var
reader: TReader;
i,x, numrows, numcols,slen: Integer;
begin
Assert(Assigned(S));
reader := TReader.Create(S, 8096);
try
numrows := reader.ReadInteger;
SetLength(A, numrows);
for i := 0 to numrows - 1 do
begin
numcols := reader.ReadInteger;
SetLength(A[i], numcols);
for x := 0 to numcols - 1 do
begin
slen := reader.ReadInteger;
SetLength(A[i,x], slen);
if slen>0 then
reader.Read(A[i, x][1], slen); // <-- !
end;
end; { For }
finally
reader.Free;
end; { Finally }
end;