2

I defined a Objectlist to store several Polygons as TFPolygon = array of TPoint inside this TObjectList; but with the add function of my objectlist I get an Access violation error :

type
  TFPolygon = array of TPoint;
  TFPolygonList = class(TObjectList)
  private
    procedure SetPolygon(Index: Integer; Value: TFPolygon);
    function GetPolygon(Index: Integer): TFPolygon;
  public
    procedure Add(p: TFPolygon);
    property Items[index: Integer]: TFPolygon read GetPolygon write SetPolygon; default;
  end;

implementation

procedure TFPolygonList.SetPolygon(Index: Integer; Value: TFPolygon);
begin
  inherited Items[Index] := Pointer(Value);
end;

function TFPolygonList.GetPolygon(Index: Integer): TFPolygon;
begin
  Result := TFPolygon(inherited Items[Index]);
end;

procedure TFPolygonList.Add(p: TFPolygon);
begin
  inherited Add(Pointer(p));
end;

I can not understand the error inside this code sample ? Can I only store classes inside a TObjectList or is my approach to store arrays of TPoints also valid ?

TLama
  • 75,147
  • 17
  • 214
  • 392
user1769184
  • 1,571
  • 1
  • 19
  • 44

1 Answers1

2

Your approach is not valid. Dynamic arrays are managed types. Their lifetimes are managed by the compiler. For that to work you must not cast away the fact that they are managed types, which is exactly what you did.

You cast the dynamic array to Pointer. At that point you have taken a new reference to the dynamic array, but the compiler is not aware of it because a Pointer is not a managed type.

You've got a few options to solve your problem.

  1. If you are on a modern Delphi then stop using TObjectList. Instead use the generic type safe containers in Generics.Collections. In your case TList<TFPolygon> is what you need. Because this is compile time type safe, all the lifetime of the managed types is taken care of.
  2. If you are on an older Delphi, then you can wrap your dynamic array inside a class. Then add instances of those classes to your TObjectList. Make sure that your list is configured to own its objects. It's perfectly possible for you to do that wrapping purely in the implementation of TFPolygonList which will encapsulate things well.
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    all my code is replaced by TFPolygonList = TList ; cool short version :-) – user1769184 Mar 27 '13 at 16:56
  • @user Yes that sounds like exactly what is needed. I don't know how we managed before generics! – David Heffernan Mar 27 '13 at 17:12
  • @Runner Well yes, generics, as implemented in Delphi, do result in bigger code. Interestingly, lots of the duplication could be folded together if the compiler was cleverer. The .net implementation does that. – David Heffernan Mar 27 '13 at 18:04
  • Sadly lots of things in Delphi could be better if they would do a little more planing and go for quality instead of quantity and the glamour. Until now I never had issues with executable sizes but they could be more optimized. – Runner Mar 27 '13 at 18:22