Search code examples
delphigenericsdelphi-2009indexof

Generic TList<> in Delphi 2009 crash on IndexOf


I've seen many mentions of bugs in Delphi 2009 generics, but never expected something so basic to fail in Update 3, no less. Calling IndexOf on a generic TList or TObjectList causes an access violation if the list contains 1 or more items:

type
  TTest = class( TObject );

procedure DoTest;
var
  list : TObjectList< TTest >;
  t : TTest;
begin
  list := TObjectList< TTest >.Create;
  try
    t := TTest.Create;
    list.IndexOf( t ); // No items in list, correct result -1
    list.Add( t );
    list.IndexOf( t ); // Access violation here
  finally
    list.Free;
  end;
end;

The exception is "EAccessViolation: Access violation at address 0048974C in module 'testbed.exe'. Read of address 00000000"

Compiling with debug DCUs leads to a problem in generics.collections.pas - the FComparer member is not assigned:

function TList<T>.IndexOf(const Value: T): Integer;
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
    if FComparer.Compare(FItems[i], Value) = 0 then
      Exit(i);
  Result := -1;
end;

This of course makes the generic TList almost completely useless. Since Update 3 does not seem to have fixed this bug, do I have a recourse other than upgrading to XE?


Solution

  • Have a look at this question. Why is TList.Remove() producing an EAccessViolation error?

    In particular, try creating your TList like this

    TList<TTest>.Create(TComparer<TTest>.Default);