[fpc-pascal] Array clearing

Sven Barth pascaldragon at googlemail.com
Tue Apr 4 16:57:36 CEST 2017


On 04.04.2017 15:40, Ryan Joseph wrote:
> 
>> On Apr 4, 2017, at 7:17 PM, Sven Barth via fpc-pascal <fpc-pascal at lists.freepascal.org> wrote:
>>
>> If you want continuous memory areas you need to use static arrays or develop your own dynamic data structure that uses array properties.
>>
>>
> 
> I’m glad I asked because of arrays of pointers is bad news for performance. Does SetLength on a single level dynamic array not even allocate a continuous block of memory? I could use GetMem and array[0..0] but it seems like dynamic arrays should do basically that anyways if they’re not nested.

You could use something along these lines instead:

=== code begin ===

program tarrtest;

{$mode objfpc}
{$modeswitch advancedrecords}

type
  generic TTwoDimArray<T> = record
  private
    fData: array of T;
    { Note: Length1 and Length2 are not initialized by default, but you
            could use trunk's management operators for that }
    fLength1,
    fLength2: LongInt;
    function GetElement(Index1, Index2: LongInt): T; inline;
    procedure SetElement(Index1, Index2: LongInt; aValue: T); inline;
  public
    { using SetLength() would lead to us needing to use
      "System.SetLength()" for the array which in turn would complain
      about usage of the static symtable; that's a problem that yet
      needs to be solved inside generics, for non-generics that would
      work however }
    procedure AdjustLength(aLength1, aLength2: LongInt);
    property Length1: LongInt read fLength1;
    property Length2: LongInt read fLength2;
    property Element[Index1, Index2: LongInt]: T read GetElement write
SetElement; default;
  end;

{ TTwoDimArray }

function TTwoDimArray.GetElement(Index1, Index2: LongInt): T;
begin
  { ToDo: Length check }
  Result := fData[Index1 * fLength1 + Index2];
end;

procedure TTwoDimArray.SetElement(Index1, Index2: LongInt; aValue: T);
begin
  { ToDo: Length check }
  fData[Index1 * fLength1 + Index2] := aValue;
end;

procedure TTwoDimArray.AdjustLength(aLength1, aLength2: LongInt);
begin
  SetLength(fData, aLength1 * aLength2);
  fLength1 := aLength1;
  fLength2 := aLength2;
end;

var
  arr: specialize TTwoDimArray<LongInt>;
  i: LongInt;
begin
  arr.AdjustLength(10, 5);
  i := arr[3, 2];
  arr[7, 1] := i;
end.

=== code end ===

Regards,
Sven




More information about the fpc-pascal mailing list