Delphi How to avoid Access violation when creating Tlist inside a Class definition

1k Views Asked by At

I have made a Class representing a 2D array of strings using a type Tlist defined as

type
  T2DimensionalStringlist =  Tlist<Tstringlist>;

  TwoDstringlistClass = class
  private
     TwoDimStringlist : T2DimensionalStringlist;

 etc.

However I get an access violation when I call the constructor. All the constructor does is create the list using

 TwoDimStringlist:= T2DimensionalStringlist.Create;

I haven't made many classes yet but the the full code of this one is at the bottom of this post.

Please can someone tell me what I have done wrong that would cause the access violation in the class constructor?

What I have tried

I've looked at this SO thread but it didn't really answer my question.

I've also tried turning the whole thing into a simple unit instead of a class and defining the list type and variable as globals eg

type
  T2DimensionalStringlist =  Tlist<Tstringlist>;
var
   TwoDimStringlist: T2DimensionalStringlist ;

Then, if I create the list in the initialization with

TwoDimStringlist:= T2DimensionalStringlist.Create;

and free it in the finalization with

for i := 0 to TwoDimStringlist.Count - 1 do
       TwoDimStringlist[i].free;
TwoDimStringlist.free;

then it works fine and I can use it as a 2D array of strings with various other procedures and functions like those in the class unit.

I've also tried moving the

type
  T2DimensionalStringlist =  Tlist<Tstringlist>;

to inside the class instead of outside but still got the error.

Here is the full code of the class

unit U_TwoDstringlist;

interface

uses
 classes,   //for Tstringlist
 Generics.Collections;  //for Tlist
type
  T2DimensionalStringlist =  Tlist<Tstringlist>;

  TwoDstringlistClass = class
  private
     TwoDimStringlist : T2DimensionalStringlist;
   public
       function AddStringlist : integer;                                 //returns index of newnly created stringlist
       function AddString(ListIndex : integer; S : string) : boolean;    //adds a string to the list at index ListIndex
       function GetStringlist(ListIndex : integer): Tstringlist;         //retuns the stringlist from index ListIndex
       function ListCount : integer ;                                    //returns number of used elements
       function StringlistCount(ListIndex : integer) : integer ;         //returns number of used elements in a particular stringlist
       function GetString(ListIndex,StringlistIndex : integer) : string; //returns string at 2D index ListIndex,StringlistIndex
   constructor Create; overload;
   destructor Destroy; override;
   end;  //class

implementation

constructor TwoDstringlistClass.Create;
begin
  TwoDimStringlist := T2DimensionalStringlist.Create;
end;

destructor TwoDstringlistClass.Destroy;
var
  i : integer;
begin
for i := 0 to TwoDimStringlist.Count - 1 do
  TwoDimStringlist[i].free;
TwoDimStringlist.free;
inherited;
end;

function TwoDstringlistClass.AddString(ListIndex: integer; S: string): boolean;
begin
    try
     TwoDimStringlist[ListIndex].add(s) ;
     result := true;
   except
      result := false;
   end;
end;

function TwoDstringlistClass.AddStringlist: integer;
begin
   TwoDimStringlist.add(Tstringlist.create);
   result :=  TwoDimStringlist.count -1;
end;

function TwoDstringlistClass.GetString(ListIndex, StringlistIndex: integer): string;
begin
try
  result := TwoDimStringlist[ListIndex][StringlistIndex];
except
  result := '';
end;
end;

function TwoDstringlistClass.GetStringlist(ListIndex: integer): Tstringlist;
begin
try
  result := TwoDimStringlist[ListIndex] ;
except
  result := nil;
end;
end;

function TwoDstringlistClass.ListCount: integer;
begin
 result := TwoDimStringlist.count;
end;

function TwoDstringlistClass.StringlistCount(ListIndex: integer): integer;
begin
try
   result :=  TwoDimStringlist[ListIndex].count
except
  result := -1
end;
end;


end.

and the main form uses this class like this

implementation
var
My2dList :  TwoDstringlistClass;

begin

procedure TForm1.btnCreateClick(Sender: TObject);
begin
 My2dList.create;
end;

etc.
0

There are 0 best solutions below