Recent

Author Topic: Free-ing objects in a generic container  (Read 255 times)

Anonimista

  • New Member
  • *
  • Posts: 19
Free-ing objects in a generic container
« on: September 17, 2019, 09:29:13 pm »
If I have a generic container and populate it with class instances:

Code: Pascal  [Select]
  1. program project1;
  2.  
  3. uses
  4.     fgl;
  5.  
  6. type
  7.  
  8.     Expression = class(TObject)
  9.     public
  10.         value: integer;
  11.         constructor Create(v: integer);
  12.     end;
  13.  
  14.     TMyList = specialize TFPGObjectList<Expression>;
  15.  
  16.  
  17. var
  18.     list: TMyList;
  19.     i: integer;
  20.     e: Expression;
  21.  
  22.  
  23. constructor Expression.Create(v: integer);
  24. begin
  25.     self.value := v;
  26. end;
  27.  
  28. begin
  29.  
  30.     list := TMyList.Create;
  31.  
  32.     for i := 1 to 10 do
  33.     begin
  34.         list.Add(Expression.Create(i));
  35.     end;
  36.  
  37.     for e in list do
  38.     begin
  39.         writeln(e.value);
  40.     end;
  41.  
  42.     list.Free;
  43.  
  44.     { Expression objects still on the heap? }
  45.  
  46.     readln;
  47.  
  48. end.

do I have to Free each object from the container explicitly before I Free the container instance? Thanks.

Bart

  • Hero Member
  • *****
  • Posts: 3516
    • Bart en Mariska's Webstek
Re: Free-ing objects in a generic container
« Reply #1 on: September 17, 2019, 10:59:13 pm »
TFPGObjectList doesn't have an OwnsObjects property or something like that.
If not, override Destroy and free all Expressions there.

Bart

howardpc

  • Hero Member
  • *****
  • Posts: 3144
Re: Free-ing objects in a generic container
« Reply #2 on: September 17, 2019, 11:17:53 pm »
The constructor of FPGObjectList is declared as follows:
Code: Pascal  [Select]
  1.     constructor Create(FreeObjects: Boolean = True);
i.e. it defaults to freeing its contained objects, unless you specify otherwise.
So your example program which includes the line

Code: Pascal  [Select]
  1. list := TMyList.Create;
correctly ensures that all Expression objects are freed.BTW is is good practice to name such classes with a leading T -- so TExpression.

simone

  • Full Member
  • ***
  • Posts: 245
Re: Free-ing objects in a generic container
« Reply #3 on: September 17, 2019, 11:19:48 pm »
The constructor of TFPGObjectList is defined as follows:

Code: Pascal  [Select]
  1. public constructor TFPGObjectList.Create(FreeObjects: Boolean = True);

Documentation says:

"If FreeObjects is true, then the list owns the objects. Freeing or clearing the list will remove all objects from memory by calling the destructor. Deleting or removing an item from the list will also dispose of the element."
(https://www.freepascal.org/docs-html/current/rtl/fgl/tfpgobjectlist.create.html)

If you enable heap trace in your code, as follows:

Code: Pascal  [Select]
  1. program project1;
  2. {$DEFINE debug}
  3. uses
  4.     fgl,sysutils;
  5.  
  6. type
  7.  
  8.     Expression = class(TObject)
  9.     public
  10.         value: integer;
  11.         constructor Create(v: integer);
  12.     end;
  13.  
  14.     TMyList = specialize TFPGObjectList<Expression>;
  15.  
  16.  
  17. var
  18.     list: TMyList;
  19.     i: integer;
  20.     e: Expression;
  21.  
  22.  
  23. constructor Expression.Create(v: integer);
  24. begin
  25.     self.value := v;
  26. end;
  27.  
  28. begin
  29.  
  30.   {$IFDEF DEBUG}
  31.   if FileExists('heap.trc') then
  32.     DeleteFile('heap.trc');
  33.   SetHeapTraceOutput('heap.trc');
  34.   {$ENDIF DEBUG}
  35.  
  36.     list := TMyList.Create;
  37.  
  38.     for i := 1 to 10 do
  39.     begin
  40.         list.Add(Expression.Create(i));
  41.     end;
  42.  
  43.     for e in list do
  44.     begin
  45.         writeln(e.value);
  46.     end;
  47.  
  48.     list.Free;
  49.  
  50.     { Expression objects still on the heap? }
  51.  
  52.     readln;
  53.  
  54. end.

After program execution you have this trace (heap.trc file):

Code: Pascal  [Select]
  1. Heap dump by heaptrc unit
  2. 64 memory blocks allocated : 2242/2432
  3. 64 memory blocks freed     : 2242/2432
  4. 0 unfreed memory blocks : 0
  5. True heap size : 196608 (160 used in System startup)
  6. True free heap : 196448

So I think that It is not necessary to delete the items in the list. In fact, if you do, a run time error occurs (SIGSEGV).
« Last Edit: September 17, 2019, 11:22:29 pm by simone »

Anonimista

  • New Member
  • *
  • Posts: 19
Re: Free-ing objects in a generic container
« Reply #4 on: September 18, 2019, 06:22:37 am »
Thanks for the replies guys, I appreciate it.