Recent

Author Topic: what about an indexed record = irecord type ?  (Read 1632 times)

JoLt

  • Newbie
  • Posts: 2
Re: what about an indexed record = irecord type ?
« Reply #15 on: September 19, 2025, 09:59:47 am »
Thanks to all for the extensive reply.

The reason I use record type is because of mixed type variables (String, Longword, Integer)
Looking at the replies I feel like the suggestion to consider creating a type irecord makes sense.
To me this would lead to a uniform way for working with records as multi-type array.

In the meantime I've considered means like using a set of strings which matches the record field names to iterate over an entire record.

Warfley

  • Hero Member
  • *****
  • Posts: 2033
Re: what about an indexed record = irecord type ?
« Reply #16 on: September 19, 2025, 06:27:36 pm »
Thank you for explanation Warfley.

I am interesting if in this situation strings will be free

And what will be in this situation

Yes and yes. In the first example you do not need to call SetLength(arr,0) because arrays will be freed even if you don't call setlength. When you free your array (either automatically or via setlength), all elements of that array will be freed. When the object is freed, all it's members are freed. If those are strings, or arrays or other objects records containing managed types, they will be also freed.

In your second example, when the function ends, the Object dies and therefore frees it's members. To visualize try the following:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2. {$ModeSwitch advancedrecords}
  3.  
  4. type
  5.   TTestRec = record
  6.     x: Integer;
  7.     class operator Initialize(var r: TTestRec);
  8.     class operator Finalize(var r: TTestRec);
  9.   end;
  10.  
  11.  
  12. class operator TTestRec.Initialize(var r: TTestRec);
  13. begin
  14.   Writeln('Init ', IntPtr(@r));
  15. end;
  16.  
  17. class operator TTestRec.Finalize(var r: TTestRec);
  18. begin
  19.   Writeln('Final ', IntPtr(@r));
  20. end;
  21.  
  22. type TTestObj = object r: TTestRec; end;
  23.  
  24. procedure TestObj;
  25. var
  26.   o: TTestObj;
  27. begin
  28.   WriteLn('TestObj ', IntPtr(@o));
  29. end;
  30.  
  31. procedure TestArray;
  32. var
  33.   arr: Array of TTestObj;
  34. begin
  35.   SetLength(arr, 10);
  36.   WriteLn('After SetLength ', IntPtr(@Arr[0]));
  37.   { Avoiding optimizer optimizing it away }
  38.   arr[0].r.x := 42;
  39. end;
  40.  
  41. begin
  42.   WriteLn('Testing Object contining managed');
  43.   TestObj;
  44.   WriteLn('Testing array of object containing managed');
  45.   TestArray;
  46.   ReadLn;
  47. end.
When TestObj is called with a local object variable, the managed record it contains is initialized. Once the function ends, the object is freed and with it the managed record:
Code: Pascal  [Select][+][-]
  1. Testing Object contining managed
  2. Init 21233476
  3. TestObj 21233476
  4. Final 21233476
When the function with the array is called, SetLength creates 10 object instances, which all initiate it's managed field. Once the function finishes the array is freed and thereby also all the objects and their members:
Code: Pascal  [Select][+][-]
  1. Testing array of object containing managed
  2. Init 21821496
  3. Init 21821500
  4. Init 21821504
  5. Init 21821508
  6. Init 21821512
  7. Init 21821516
  8. Init 21821520
  9. Init 21821524
  10. Init 21821528
  11. Init 21821532
  12. After SetLength 21821496
  13. Final 21821496
  14. Final 21821500
  15. Final 21821504
  16. Final 21821508
  17. Final 21821512
  18. Final 21821516
  19. Final 21821520
  20. Final 21821524
  21. Final 21821528
  22. Final 21821532

Basically the same happens with Strings, where ever call to Final would free the containing string

 

TinyPortal © 2005-2018