Search code examples
arraysdelphitlist

Arrays in TList


I Tlist into the Array of string not much of a problem here, but I'm throwing Array I want to list all the value is going to last.

It's The last value is listed every time. I want Like that

Value1q

Value2q

Value3q

bla bla. So TList in the Array I want to list all the elements.

And sorry my bad english

public  var
  { Public declarations }
  Address : Array Of String;
  AddressList: Tlist;


//Form Create
 AddressList := Tlist.Create;
 SetLength(Address, 3);



//Copy Listview Button
var
  i : integer;
  AItem: TlistItem;
begin
  AddressList.Clear;

  for i := 0 to SelectedListView.Items.Count - 1 do
  begin
    AItem := SelectedListView.Items.Item[i];
    Address[0] := AItem.SubItems[0];
    Address[1] := AItem.Caption;
    Address[2] := AItem.SubItems[1];
    AddressList.Add(Address);
  end;

//Always being counted towards the last value
for i := 0 to AddressList.Count -1 do
    MultiUser.Text := TArrayStr(AddressList[i])[1]);

Solution

  • The problem that I see here is that a dynamic array is a managed type, and that relies on reference counting. The reference counting only works so long as the array is referenced by correctly typed variables. When you store to untyped Pointer, as you do with TList, the compiler cannot count the references properly.

    On top of that basic design flaw, you only actually have one array in your program. You just add the same pointer to the TList object every time you call Add. Remember that dynamic arrays are reference types, without any copy-on-write. So they behave like true references.

    If you have a modern Delphi then you solve this with a generic container that is typesafe. For instance TList<TArray<string>> where TList<T> is from Generics.Collections.

    For legacy versions of Delphi you cannot expect to store a dynamic array in a TList. That just will not fly at all. You can hack the reference counting yourself, but you need to clear hand and a good understanding. The next coder that comes across your code will despise you.

    So, for legacy versions of Delphi I suggest that you replace TList with TObjectList. Set OwnsObjects to True. And replace the dynamic array of string with a TStringList.

    An alternative solution for legacy Delphi would be to use a multi-dimensional array: array of array of string.