Mega Code Archive

 
Categories / Delphi / Strings
 

Creating dynamic arrays

Is it possible to re-size arrays at runtime? -------------------------------------------------------------------------------- I came across an example of how to do one. The author is Ben Licht, who presents an age-old Pascal method of creating a dynamic array. The trick is using a pointer to an array with a size of 1, then allocating memory for the pointer by multiplying the number of items you want in the array by the size of the array type. Here's a sample unit I've adapted from his example: {This unit demonstrates how to implement a dynArray} unit U; interface uses SysUtils, WinTypes, WinProcs, Classes, Controls, Forms, Dialogs, StdCtrls; type TResizeArr = array[0..0] of string; PResizeArr = ^TResizeArr; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; procedure DefineDynArray(var h : THandle; {Handle to mem pointer} NumElements : LongInt; {Number of items in array} var PArr : PResizeArr); {Pointer to array struct} procedure TestDynArray; implementation {$R *.DFM} {============================================================================ Procedure that defines the dynarray. Note that the THandle and Pointer to the array are passed by reference. This enables them to be defined outside the scope of this procedure. ============================================================================} procedure DefineDynArray(var h : THandle; {Handle to mem pointer} NumElements : LongInt; {Number of items in array} var PArr : PResizeArr); {Pointer to array struct} begin {Allocate Windows Global Heap memory} h := GlobalAlloc(GMEM_FIXED, NumElements * sizeof(TResizeArr)); PArr := GlobalLock(h); end; {============================================================================ Procedure that uses the DefineDynArray proc. This is pretty useless, but provides a good example of how you can access the elements of the 'array' once the array is defined. ============================================================================} procedure TestDynArray; var MyArray : PResizeArr; I : Integer; str : String; h : THandle; begin str := ''; DefineDynArray(h, 10, MyArray); {Define the 'array'} for I := 0 to 9 do MyArray^[I] := IntToStr(I); for I := 0 to 9 do str := str + MyArray^[I] + ','; ShowMessage(str); GlobalUnlock(h); {Must make a call to unlock the memory, then} GlobalFree(h); {free the memory and invalidate the handle} end; procedure TForm1.Button1Click(Sender: TObject); begin TestDynArray; end; end. This is a perfect example of one of those programming things that take hours to figure out, but turn out to be amazingly simple. But I should point out that it might just be simpler to use a TList, which does all of the above, but has methods to insert and delete items. It's only limited by the amount of memory you have.