Clear a TList or a TObjectList
Solution 1
1. TList won't free the elements, with both Clear
or Free
.
aList.Clear;
Will just set aList.Count := 0
without freeing the aList.Items[]
elements. So you'll leak memory. You'll need an explicit free as such:
for i := 0 to aList.Count-1 do
TObject(aList[i]).Free;
But this is what TObjectList
does... :)
About TObjectList
, it is worth saying that TObjectList.Destroy
is calling Clear
.
So
aObjectList.Clear;
aObjectList.Free;
is exactly the same as
aObjectList.Free;
2. To store a list of records, you can use a dynamic array.
You'll get all TList
methods (and more) with our dynamic array wrapper. That is, Add / Delete / Clear / Count / IndexOf / Find
...
It has built-in serialization features (in binary or JSON), automated sorting and comparison (using RTTI) which are not existing with a TList/TObjectList
. From Delphi 5 and later.
With more modern version of Delphi, you may use generics to handle the dynamic array, if you do not want to use a third-party library.
Solution 2
It's not the same TList.Clear
only frees the memory allocated to store the pointers, not objects they are pointing to.
To avoid memory leaks you need to free the memory yourself - as you have been doing - or use TObjectList
.
To answer the second question, TObjectList
doesn't support storing records. You need to use TList
(or something else) in that case.
Solution 3
Read what the documentation is saying more carefully:
Clear also frees the memory used to store the Items array
Only the memory for the array itself is freed, not the memory used by individual elements inside the array.
Solution 4
If you are using a recent version of Delphi I suggest that you use a generic list.
Right now you probably need to do a lot of casting when you use the objects from the list. With a generic list you don't have to do that anymore.
For instance if you have:
TMyObject = class(TObject);
Then you make the list like this:
TMyObjectList = TObjectList<TMyObject>;
There is an article in the Embarcadero Wiki:
http://docwiki.embarcadero.com/CodeExamples/XE8/en/Generics_Collections_TObjectList_(Delphi)
Roland Bengtsson
Middle aged man who grown up in Skattagård outside Falkenberg, Sweden Now I live in Nedervetil, Finland and work as Delphi developer on Attracs
Updated on August 14, 2020Comments
-
Roland Bengtsson over 3 years
I'm a bit puzzled of what to use for storing objects in a list. Until now I have used
TList
and freed each item in a loop. Then I discoveredTObjectList
that do this automatically fromFree
. Then I saw this from the doc ofTList.Clear
:Call
Clear
to empty the Items array and set theCount
to 0.Clear
also frees the memory used to store theItems
array and sets theCapacity
to 0.So it is basically the same. So
for
TList
mylist.Clear; myList.Free;
is the same as for
TObjectList
?myList.Free;
Can
TObjectList
only be used for items as classes or can I store records? -
LU RD almost 12 yearsJust a clearification about
TObjectList
. It has a property:OwnsObjects
(default = true) which controls if the objects in the list are being freed when items are removed. -
Arnaud Bouchez almost 12 years@LURD You are right. This property may be handy, but also misleading: you may suppose that objects will be freed, but if you set
OwnObjects := false
somewhere in the code (even at runtime), you would easily leak memory or resources: so to be used with care! I prefer a clearTList / TObjectList
separation. -
NGLN almost 12 yearsKnow managing records in a
TList
requires quite some effort though. -
LU RD over 10 yearsThe property
TObjectList.OwnsObjects
is true by default. You can change the property value after creation. If this property is true when callingTObjectList.Free
, all objects in the list will be deallocated automatically.