Recent

Author Topic: TFPGMap - does it free objects ?  (Read 2457 times)

egsuh

  • Hero Member
  • *****
  • Posts: 1800
TFPGMap - does it free objects ?
« on: October 22, 2025, 07:38:01 am »
Simply checking...

In the case like

Code: Pascal  [Select][+][-]
  1. type
  2.    TaqVar = class
  3.        ....
  4.     end;
  5.    TaqVarList = class(specialize TFPGMap<string, TaqVar>);
  6.  
  7. begin
  8.     AqVarList := TaqVarList.Create;
  9.  
  10.     AQVar := TaqVar.Create;
  11.     AqVarList.Add ('1', aqvar);
  12.  
  13.     AqVarList.Free;
  14. end;

AFAIK I have to FREE aqvar MYSELF in the above case. Am I right?

Thaddy

  • Hero Member
  • *****
  • Posts: 19268
  • Glad to be alive.
Re: TFPGMap - does it free objects ?
« Reply #1 on: October 22, 2025, 07:45:42 am »
For FGL
You should use TFPGMapObject with TFPGMapObject.Create(true);//owns objects/classes
See: https://www.freepascal.org/docs-html/current/rtl/fgl/tfpgmapobject.create.html
 
The standard map TFPGMap does not free objects.

For generics.collections you could use TObjectDictionary ( a map is the exact same as a dictionary )
example:
Code: Pascal  [Select][+][-]
  1. {$ifdef fpc}{$mode objfpc}{$endif}
  2. uses classes,fgl; // or generics.collections;
  3. type
  4.    TStrListMap = specialize TFPGMapObject<string,TStringlist>;
  5.    // for rtl generics: TStrListMap = specialize TObjectDictionary<string,TStringList>;
  6. var
  7.    testmap:TStrListMap;  
  8. begin
  9.    testmap := TStrlistMap.Create(true);// owns objects
  10.   // for ttl generics: TStrlistMap.Create([doOwnsValues]);
  11.    try
  12.      testmap.add('a',TStringlist.Create);
  13.      testmap.add('b',TStringlist.Create);
  14.      testmap.add('c',TStringlist.Create);
  15.    finally
  16.      testmap.free; // no leaks when the map is freed.
  17.    end;
  18. end.
« Last Edit: October 22, 2025, 09:00:57 am by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

egsuh

  • Hero Member
  • *****
  • Posts: 1800
Re: TFPGMap - does it free objects ?
« Reply #2 on: October 22, 2025, 07:58:50 am »
Quote
For FGL
You should use TFPGMapObject with TFPGMapObject.Create(true);//owns objects/classes
See: https://www.freepascal.org/docs-html/current/rtl/fgl/tfpgmapobject.create.html
For reference counted classes you could use TFPGMapInterfacedObjectData and add interface references.
 
The standard map TFPGMap does not free objects.

I know. I have several objects, which should be ordered in different ways.
So I have only one TFPGMapObject, and two TFPGMaps, all share the same objects.

Thaddy

  • Hero Member
  • *****
  • Posts: 19268
  • Glad to be alive.
Re: TFPGMap - does it free objects ?
« Reply #3 on: October 22, 2025, 09:39:56 am »
Can't you solve that by using different enumerators?
objects are fine constructs. You can even initialize them with constructors.

cdbc

  • Hero Member
  • *****
  • Posts: 2814
    • http://www.cdbc.dk
Re: TFPGMap - does it free objects ?
« Reply #4 on: October 22, 2025, 10:38:30 am »
Hi
Quote
So I have only one TFPGMapObject, and two TFPGMaps, all share the same objects.
If I read you correctly, this organisation shouldn't pose any problem:
· they share the same objects ...an object can only be free'd once.
· so, you keep all your objects in the 'fpgobjectmap' which /owns/ them
· you fetch objects temporarily and keep them in the std. fpgmap for use
  (you are just borrowing them - no need to free)
· then you /borrow/ another set of objects and keep them in another fpgmap
  (again - no need to free them)
· in the end you're all done and the fpgobjectmap will free all objects...!
I don't see a problem in that  %)
...Otherwise you'll have to explain exactly what you're trying to do.
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Thaddy

  • Hero Member
  • *****
  • Posts: 19268
  • Glad to be alive.
Re: TFPGMap - does it free objects ?
« Reply #5 on: October 22, 2025, 12:50:55 pm »
What I mean is that you only need one list.
Suppose I want to access the list items in reversed order, you can do that like :
Code: Pascal  [Select][+][-]
  1. // reverse access
  2.    function reverseindex(const list:TStrlistMap; i:integer):integer;inline;
  3.    begin
  4.      result := pred(List.Count)-i;
  5.    end;
Writing an accessor is more efficient than maintaining three lists.

« Last Edit: October 22, 2025, 12:53:58 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

cdbc

  • Hero Member
  • *****
  • Posts: 2814
    • http://www.cdbc.dk
Re: TFPGMap - does it free objects ?
« Reply #6 on: October 22, 2025, 02:06:20 pm »
Hi
Yes, Thaddy, that's what I mean, there are other ways to achieve the end-goal...
He'll just have to explain what he wants...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

egsuh

  • Hero Member
  • *****
  • Posts: 1800
Re: TFPGMap - does it free objects ?
« Reply #7 on: October 26, 2025, 02:18:30 pm »
I'll look for other ways, but this is weired.

Code: Pascal  [Select][+][-]
  1. type
  2.    TaqVarList = specialize TFPGMap<string, TaqVar>;
  3.    TaqVarObjectList = specialize TFPGMapObject<string, TaqVar>;
  4.  
  5. var
  6.    AVar: TaqVar;
  7.    QVarList,
  8.    VarList : TaqVarList;
  9.    OrderedVarList: TaqVarObjectList;
  10.  
  11. begin
  12.    QVarList := TaqVarList.Create;
  13.    VarList := TaqVarList.Create;
  14.    OrderedVarList:= TaqVarObjectList.Create;
  15.    
  16.     for ti := 0 to N do begin
  17.          for tj := 1 to N2 [ti] do begin
  18.               avar := TaqVar.Create;
  19.               QVarList.Add(IntToStr(ti * N + tj), avar);
  20.          end;    
  21.          VarList.AddList(QVarList);
  22.          QVarList.Clear;
  23.     end;  
  24.  
  25.     OrderedVarList.AddList(VarList);   // this cause problem at CLOSING application.
  26.  
  27.      // but.. following does not cause problem.
  28.      for i := 0 to VarLIst.Count - 1 do
  29.           OrderedVarList.Add(VarList.Keys[i], VarList.Data[i]);
  30.  
  31.      // however, following CAUSE problem
  32.  
  33.      for i := 0 to VarLIst.Count - 1 do
  34.           OrderedVarList.Add(NewOrderStr[i], VarList.Data[i]);  // the orders are changed here.  
  35.  
  36.      qvarlist.free;
  37.      varlist.free;
  38.      orderedvarlist.free;
  39. end ;


Theoretically this should work correctly, which is not. I can find other way around, but hope anybody to check whether this is constant phenomenon. If yes, I think this is bug.

The problem is "Access violation" at the termimation of application. Not during run-time.

cdbc

  • Hero Member
  • *****
  • Posts: 2814
    • http://www.cdbc.dk
Re: TFPGMap - does it free objects ?
« Reply #8 on: October 26, 2025, 02:37:25 pm »
Hi
Of course that should NOT work  >:D
All the 'AVar' objects, you assign to a map that DOESN'T free objects!!!!!!!!
Only the accumulated lists you assign to an object-map, this /construct/ of yours will leak so hard, you might as well piss in your pants!!!
Back to the studying with you.
/bc
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

egsuh

  • Hero Member
  • *****
  • Posts: 1800
Re: TFPGMap - does it free objects ?
« Reply #9 on: October 26, 2025, 02:52:01 pm »
They are freed by orderedvarlist. There are no leakages. Access Violation, I told.

Thaddy

  • Hero Member
  • *****
  • Posts: 19268
  • Glad to be alive.
Re: TFPGMap - does it free objects ?
« Reply #10 on: October 26, 2025, 05:10:31 pm »
The creation order is wrong. The ordered object map should be first created and last released.
And the constructor is not the correct constructor: TFpgMapObject.Create(true); otherwise the objects are not owned.
« Last Edit: October 27, 2025, 05:32:53 am by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

egsuh

  • Hero Member
  • *****
  • Posts: 1800
Re: TFPGMap - does it free objects ?
« Reply #11 on: October 27, 2025, 04:01:09 am »
I solved my own problem. I need further tests, but I think followings are bugs. Please read undefined variable names of my examples intuitively.

My situation is that my objects are created, but later I have to output them in different order from creation.

If defined as follow,

Code: Pascal  [Select][+][-]
  1. type
  2.      TMap = specialize TFPGMap<string, TAclass>;
  3.      TObjMap = specialize TFPGMapObject<string, TAClass>;
  4.  
  5. var
  6.     Map: TMap;
  7.     ObjMap: TObjMap;
  8.  
  9. begin
  10.     Map.Sorted := True;
  11.     ObjMap.Sorted := True;
  12.  

1.   TObjMap.AddList(TMap) does not work correctly. No compilation error, no runtime error but results are not what I expect.

Code: Pascal  [Select][+][-]
  1.     ObjMap.AddList (Map);    // --> this does not work correctly.
  2.  
  3.      // Instead, I have to use
  4.  
  5.     for ti := 0 to Map.Count-1 do begin
  6.          AClass := Map.Data[ti];
  7.          ObjMap.Add(Map.Keys[ti], AClass);
  8.     end;
  9.  

2.   Either with TMap or TObjMap, reordering with the same objects cause problems. I mean "later problem", not at compilation or execution.  For example.

Code: Pascal  [Select][+][-]
  1.     for ti := 0 to Map.Count-1 do begin
  2.          AClass := Map.Data[ti];
  3.          Map2.Add(NewOrderKey, AClass);   // NewOrderKey is a string. The whole order of list should be decided based on this.
  4.     end;
  5.  

executes well.  But it causes "Access Violation" at termination of application.


I have solved my own problem by mediating as follows.

Code: Pascal  [Select][+][-]
  1.     for ti := 0 to Map.Count-1 do begin
  2.          Map2.Add(NewOrderKey, Map.Key[ti]);
  3.     end;
  4.  
  5.     // and later in use,
  6.  
  7.     for tj := 0 to Map2.Count-1 do begin
  8.         AClass := Map.KeyData[Map2.Data[tj];
  9.  
  10.         // output AClass
  11.    end;
  12.  


« Last Edit: October 27, 2025, 04:13:15 am by egsuh »

Thaddy

  • Hero Member
  • *****
  • Posts: 19268
  • Glad to be alive.
Re: TFPGMap - does it free objects ?
« Reply #12 on: October 27, 2025, 05:54:45 am »
You have
Code: Pascal  [Select][+][-]
  1.     OrderedVarList.AddList(VarList);   // this cause problem at CLOSING application.
When adding a list, set it to unsorted, then sort.
objects are fine constructs. You can even initialize them with constructors.

egsuh

  • Hero Member
  • *****
  • Posts: 1800
Re: TFPGMap - does it free objects ?
« Reply #13 on: October 27, 2025, 06:09:45 am »
Quote
When adding a list, set it to unsorted, then sort.

Is duplication check possible with unsorted list?  Anyway this does not work either.

« Last Edit: October 27, 2025, 06:19:45 am by egsuh »

Thaddy

  • Hero Member
  • *****
  • Posts: 19268
  • Glad to be alive.
Re: TFPGMap - does it free objects ?
« Reply #14 on: October 27, 2025, 09:31:53 am »
The problem is easier to remedy with rtl-generics, because that let's you choose if the keys and/or the values are owned.
But I am just guessing, because I have to turn your examples into compilable code every time.
objects are fine constructs. You can even initialize them with constructors.

 

TinyPortal © 2005-2018