Error in free TStringList object
procedure FreeListObjects( l : TStrings);
var i : integer;
BEGIN
FOR i := 0 TO l.Count -1 DO BEGIN
l.Objects[i].Free;
l.Objects[i] := NIL;
END;
end;
PROCEDURE StringListAdd;
VAR i : INTEGER; Code : LONGWORD;
BEGIN
l := Classes.TstringLIST.CREATE;
FOR i := 0 TO 4 DO BEGIN
Code := i ;
l.AddObject('', TObject(code));
END;
Code := LONGWORD(l.Objects[2]);
FreeListObjects(l);
l.Free;
END;
When I use l.OwnsObjects := TRUE
without FreeListObjects(l)
, an error occurs.
Who should free these string list objects?
You told the list of strings that it owns the objects in the array Objects
. In this case, it will automatically call Free
for all these values when the list is destroyed, as your code does FreeListObjects
.
But there are no objects there! You have taken values Integer
that are not objects and typecast them to force them into TObject
. You can't call Free
on Integer
, but at the point where any code calls Free
, it doesn't know the original type of the values. When you type, you tell the compiler that you know what you are doing, and the compiler believes you. If you really don't know what you are doing, do not type.
You say you get errors without FreeListObjects
, but you should also get errors with FreeListObjects
. The problem is that you are calling Free
on something that is not an object. If you call it in your own code, or if you let the library call it, it doesn't matter.
You may have spent some time using C #. In this language, integers are automatically "boxed" to be real objects. This is not how Win32 Delphi works. Delphi does not box for unpacking.
source to share
OwnsObjects does basically the same thing as your FreeObjects procedure, but it handles it internally when the StringList itself is freed.
But it seems to me that your problem is coming from your example. When I run this, I get access violations because your "objects" you are storing are not objects, they are integers that you coerce the TObject word.
It's just a guess, but are you just learning Delphi, after a background in some other language where "everything is an object"? This is not the case in Delphi. Objects are one data type out of many, and you cannot call Free on other data types.
source to share
The problem is that when you set OwnObjects: = true, the list will be called for free for every item inside it. But, since you are only casting your integers into the TObject and you are not actually creating an Integer object, you cannot call any method on that cast object.
The solution to your problem is to create a class like this:
TInteger = class
value: integer;
constructor Create(v: integer);
end;
and put in the list the elements that are instances of this class, replacing:
l.AddObject('', TObject(code));
from
l.AddObject('', TInteger.Create(code));
source to share
Expanding on Rob's answer: you are trying to free something related to addresses: nil, 0x00000001, 0x00000002, 0x00000003, and 0x00000004 respectively. Since there are no valid objects there, there will be an access violation (note: calling Free on nil object does not result in an error).
source to share
Sorry, this is my first time on stackoverflow, next time I will be more precise in my questions. I thought l.addobject would create and add the object to the tstringlist. Does l.addobject ('', tobject (code)) (where l is tstringlist and code is longword) leak memory or not? when is the slogan found? I can always get the code: = Longword (L.objects [i]); what object am I licking in type?
source to share
I know that in Delphi you need to free every object by following these steps.
if your objects are of the following class eg.
TheClass = Class(TObject)
public
thestr:String;
end;
Then this is how you would do it:
procedure FreeListObjects( l : TStrings);
var i : integer;
BEGIN
FOR i := 0 TO l.Count -1 DO BEGIN
TheClass(l.Objects[i]).Free; <----
l.Objects[i] := NIL;
END;
end;
Each object in the TStrings list is actually in its own memory, even if you deallocate the pointer to your objects. You have to free the memory of objects by doing the above. This is how I do it and did it in Delphi. He always worked for me.
source to share