Reputation: 71
I have this code in Delphi 4. I created 10 objects of type T_Charge
(see below), which I added to a TList
, named myList
. The T_Charge
type has references to three objects of type T_Platte
(see below).
What is the correct way of freeing all the memory of all 10 objects? So, for every object I want to free the memory of P1
, P2
, P3
, F_Treated
and so on, as well as the memory of myCharge
itself.
I tried about everything, but keep getting errors.
procedure Test;
var
myList: TList;
myCharge: T_Charge;
begin
myList := TList.Create;
for i := 0 to 9 do
begin;
myCharge := T_Charge.Create(...);
myList.Add(myCharge);
end;
...
end;
type
T_Platte = class(TObject)
private
F_Nummer : Integer;
F_Los : Integer;
F_Dicke : Real;
F_Lange : Real;
F_Breite : Real;
F_QuenchCode : Integer;
F_Geschwindigkeit : Real;
F_Menge : Integer;
F_MengeInLos : Integer;
F_Treated : Boolean;
public
constructor Create(inNummer, inLos: Integer; inDicke, inLange, inBreite, inGeschwindigkeit : Real; inQuenchCode,inMenge: Integer; inTreated: Boolean); overload;
constructor Create(inPlatte: T_Platte); overload;
destructor Destroy; override;
property Nummer: Integer read F_Nummer write F_Nummer;
property Los: Integer read F_Los write F_Los;
property Dicke: Real read F_Dicke write F_Dicke;
property Lange: Real read F_Lange write F_Lange;
property Breite: Real read F_Breite write F_Breite;
property QuenchCode : Integer read F_QuenchCode write F_QuenchCode;
property Geschwindigkeit: Real read F_Geschwindigkeit write F_Geschwindigkeit;
property Menge: Integer read F_Menge write F_Menge;
property MengeInLos: Integer read F_MengeInLos write F_MengeInLos;
property Treated: Boolean read F_Treated write F_Treated;
function getPlattenRecord: string;
end; // class T_Platte
T_Charge = class(TObject)
private
F_P1 : T_Platte;
F_P2 : T_Platte;
F_P3 : T_Platte;
F_Treated : Boolean;
F_Vmin : Real;
F_Qty : Integer;
F_RelationNext : Boolean;
public
constructor Create(inP1, inP2, inP3 : T_Platte; inTreated: Boolean; inVmin: Real; inQty: Integer; inRelationNext: Boolean); overload;
constructor Create(inCharge : T_Charge); overload;
destructor Destroy; override;
property P1: T_Platte read F_P1 write F_P1;
property P2: T_Platte read F_P2 write F_P2;
property P3: T_Platte read F_P3 write F_P3;
property Treated : Boolean read F_Treated write F_Treated;
property Vmin : Real read F_Vmin write F_Vmin;
property Qty : Integer read F_Qty write F_Qty;
property RelationNext : Boolean read F_RelationNext write F_RelationNext;
function getChargeRecord: string;
end; // class T_Charge
constructor T_Platte.Create(inNummer, inLos: Integer; inDicke, inLange, inBreite, inGeschwindigkeit: Real; inQuenchCode,inMenge: Integer; inTreated: Boolean);
begin
F_Nummer := inNummer;
F_Los := inLos;
F_Dicke := inDicke;
F_Lange := inLange;
F_Breite := inBreite;
F_Geschwindigkeit := inGeschwindigkeit;
F_QuenchCode := inQuenchCode;
F_Menge := inMenge;
F_MengeInLos := 0;
F_Treated := inTreated;
end;
constructor T_Charge.Create(inP1, inP2, inP3 : T_Platte; inTreated: Boolean; inVmin: Real; inQty: Integer; inRelatio nNext: Boolean);
begin
F_P1 := T_Platte.Create(inP1);
F_P2 := T_Platte.Create(inP2);
F_P3 := T_Platte.Create(inP3);
F_Treated := inTreated;
F_Vmin := inVmin;
F_Qty := inQty;
F_RelationNext := inRelationNext;
end;
Upvotes: 6
Views: 12707
Reputation: 31
Little knowledge of classes: TList vs TObjectList
TList holds Pointers
so has no idea of how to free any TObject
stored
TObjectList hols TObjects
, so can free them and does it automatically
My best i can say: Use TObjectList
instead of TList
as your base class or type declaration.
Samples:
Wrong: TMyListOfObjects=class(TList) ...
Good: TMyListOfObjects=class(TObjectList) ...
Wrong: MyListOfObjects:TList;
Good: MyListOfObjects:TObjectList;
Note: TList
is declared on unit classes
and TObjectList
is declared on Contnrs
, that makes so many people use TList
and do not know anything about TObjectList
(also me before i read about TObjectList
on Internet some time ago).
Upvotes: 3
Reputation: 3349
Specifically when a list should hold class instances I think you should rather use TObjectList
for that purpose (TObjectList). Call the constructor of the TObjectList
with Create(True)
which tells the list to free all contained class instances once the list gets destroyed or you remove an item from it. Nevertheless, as mentioned in Ken White's answer you still need to free F_P1 etc. in the T_Charge destructor.
Upvotes: 4
Reputation: 772
To free the list objects, create your list and override TList.Notify().
procedure THotFixList.Notify(Ptr: Pointer; Action: TListNotification);
begin
inherited;
if Action = lnDeleted then
Tobject(Ptr).Free;
end;
It will ensure your objects are freed whenever you call TLIst.Delete, TList.Clear, TList.Free, without having to iterate the list yourself each time.
Upvotes: 8
Reputation: 125620
Add the following to the destructor for T_Charge
:
destructor T_Charge.Destroy;
begin
F_P1.Free;
F_P2.Free;
F_P3.Free;
// Other code as needed
inherited;
end;
Before you free your list, loop through and delete each T_Charge
:
for i := 0 to myList.Count - 1 do
TObject(myList[i]).Free; // This will free the inner `T_Platt3`
// each `T_Charge` contains.
Upvotes: 5
Reputation: 1768
Before destroying myList you need:
for i := 0 to myList.Count - 1 do
begin;
TObject(myList[i]).Free
end;
In the destructor for T_Charge you need to free F_P1, F_P2 and F_P3.
Upvotes: 2
Reputation: 34889
Don't forget to type cast the items, since they holds a pointer without type !
for i := 0 to myList.Count - 1 do
begin
T_Charge(myList[i]).Free; // Type cast
end;
Upvotes: 3