[Back to DELPHI SWAG index] [Back to Main SWAG index] [Original]

    {
    Dynamic Arrays

    Is it possible to create a dynamically-sized array in Delphi?

    Yes.  First, you need to create an array type using the largest
    size you might possibly need.  When creating a type, no memory
    is actually allocated.  If you created a variable of that type,
    then the compiler will attempt to allocate the necessary memory
    for you.  Instead, create a variable which is a pointer to that
    type.  This causes the compiler to only allocate the four bytes
    needed for the pointer.

    Before you can use the array, you need to allocate memory for
    it.  By using AllocMem, you will be able to control exactly how
    many bytes are allocated.  To determine the number of bytes
    you'll need to allocate, simply multiply the array size you
    want by the size of the individual array element.  Keep in mind
    that the largest block that can be allocated at one time in a
    16-bit environment is 64KB.  The largest block that can be
    allocated at one time in a 32-bit environment is 4GB.  To
    determine the maximum number of elements you can have in your
    particular array (in a 16-bit environment), divide 65,520 by
    the size of the individual element.
    Example:  65520 div SizeOf(LongInt)

    Example of declaring an array type and pointer:
    }
    type
      ElementType = LongInt;

    const
      MaxArraySize = (65520 div SizeOf(ElementType));
        (* under a 16-bit environment *)

    type
      MyArrayType = array[1..MaxArraySize] of ElementType;
    var
      P: ^MyArrayType;

    const
      ArraySizeIWant: Integer = 1500;

    Then when you wish to allocate memory for the array, you could
    use the following procedure:

    procedure AllocateArray;
    begin
      if ArraySizeIWant <= MaxArraySize then
        P := AllocMem(ArraySizeIWant * SizeOf(LongInt));
    end;

    Remember to make sure that the value of ArraySizeIWant is less
    than or equal to MaxArraySize.

    Here is a procedure that will loop through the array and set a
    value for each member:

    procedure AssignValues;
    var
      I: Integer;
    begin
      for I := 1 to ArraySizeIWant do
        P^[I] := I;
    end;

    Keep in mind that you must do your own range checking.  If you
    have allocated an array with five members and you try to assign
    a value to the sixth member of the array, you will not receive
    an error message.  However, you will get memory corruption.

    Remember that you must always free up any memory that you
    allocate.  Here is an example of how to dispose of this array:

    procedure DeallocateArray;
    begin
      P := AllocMem(ArraySizeIWant * SizeOf(LongInt));
    end;

    Below is an example of a dynamic array:

    }

    unit Unit1;

    interface

    uses
      SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,
      Controls, Forms, Dialogs, StdCtrls;

    type
      ElementType = Integer;

    const
      MaxArraySize = (65520 div SizeOf(ElementType));
        { in a 16-bit environment }

    type
      { Create the array type.  Make sure that you set the range to
        be the largest number you would possibly need. }
      TDynamicArray = array[1..MaxArraySize] of ElementType;
      TForm1 = class(TForm)
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

    var
      Form1: TForm1;
      { Create a variable of type pointer to your array type. }
      P: ^TDynamicArray;

    const
      { This is a typed constant.  They are actually static
        variables hat are initialized at runtime to the value taken
        from the source code.  This means that you can use a typed
        constant just like you would use any other variable.  Plus
        you get the added bonus of being able to automatically
        initialize it's value. }
      DynamicArraySizeNeeded: Integer = 10;

    implementation

    {$R *.DFM}

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      { Allocate memory for your array.  Be very careful that you
        allocate the amount that you need.  If you try to write
        beyond the amount that you've allocated, the compiler will
        let you do it.  You'll just get data corruption. }
      DynamicArraySizeNeeded := 500;
      P := AllocMem(DynamicArraySizeNeeded * SizeOf(Integer));
      { How to assign a value to the fifth member of the array. }
      P^[5] := 68;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      { Displaying the data. }
      Button1.Caption := IntToStr(P^[5]);
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      { Free the memory you allocated for the array. }
      FreeMem(P, DynamicArraySizeNeeded * SizeOf(Integer));
    end;

    end.

[Back to DELPHI SWAG index] [Back to Main SWAG index] [Original]