Recent

Author Topic: Is there an error in the description of the "record"?  (Read 1288 times)

beria

  • Jr. Member
  • **
  • Posts: 70
Re: Is there an error in the description of the "record"?
« Reply #15 on: September 20, 2022, 04:56:18 pm »
This is how to write it with the implicit initialize/finalize. You may still want to add the explicit constructor:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$modeswitch advancedrecords} // or simply only {$mode delphi}
  2. type
  3.   pdatao= ^datao;
  4.   datao = record
  5.     Data: Pointer;
  6.     constructor init(size:PtrUint);
  7.     Class operator initialize(var rec:datao);
  8.     Class operator finalize(var rec:datao);
  9.   end;
  10.  
  11.   constructor datao.init(size:ptrUint);
  12.   begin
  13.     Data := ReAllocMem(Data,size);  // realloc, because initialize has already allocated data.
  14.   end;
  15.  
  16.   class operator datao.initialize(var rec:datao);
  17.   begin
  18.     rec.Data := AllocMem(250);
  19.     writeln('At initialization 250 bytes allocated for data');
  20.   end;
  21.  
  22.   class operator datao.finalize(var rec:datao);
  23.   begin
  24.     FreeMem(Rec.Data);
  25.     writeln('At finalization, data is free''d');    
  26.   end;      
  27.  
  28. var
  29.   d: pdatao;
  30. begin
  31.   New(d);
  32.   Dispose(d);
  33. end.

I didn't know you could do that. Thank you. It's the perfect way.


KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Is there an error in the description of the "record"?
« Reply #16 on: September 20, 2022, 05:12:01 pm »
This is how to write it with the implicit initialize/finalize. You may still want to add the explicit constructor
Thanks a lot for your snippet!
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Is there an error in the description of the "record"?
« Reply #17 on: September 21, 2022, 08:46:54 am »
As it is, I discovered a bug that caused a double free if you call dispose instead of freemem because data should be set to nil after the call to freemem.
I corrected that code, with an example call to the explicit constructor.
Code: Pascal  [Select][+][-]
  1. {$mode delphi} // or {$mode objfpc}{$modeswitch advancedrecords}
  2. type
  3.   pdatao= ^datao;
  4.   datao = record
  5.     Data: Pointer;
  6.     constructor init(size:PtrUint);
  7.     Class operator initialize(var rec:datao);
  8.     Class operator finalize(var rec:datao);
  9.   end;
  10.  
  11.   constructor datao.init(size:ptrUint);
  12.   begin
  13.      ReAllocMem(Data,size);  // realloc, because initialize has already allocated data.
  14.   end;
  15.  
  16.   class operator datao.initialize(var rec:datao);
  17.   begin
  18.     rec.Data := AllocMem(250);
  19.     writeln('At initialization 250 bytes allocated for data');
  20.   end;
  21.  
  22.   class operator datao.finalize(var rec:datao);
  23.   begin
  24.     FreeMem(Rec.Data);
  25.     Rec.Data := nil;  // otherwise double free.
  26.     writeln('At finalization data is free''d');
  27.   end;      
  28.  
  29. var
  30.   d: pdatao;
  31. begin
  32.   New(d);
  33.   d^.init(400);
  34.   dispose(d);
  35. end.
The bug was only using the explicit constructor.
There is still a peculiarity, though:
If you define an explicit constructor, finalize is called twice, harmless but superfluous.
If you change the explicit constructor to a procedure this does not happen.

Maybe PascalDragon can shed some light on it.
« Last Edit: September 21, 2022, 10:24:10 am by Thaddy »
Specialize a type, not a var.

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Is there an error in the description of the "record"?
« Reply #18 on: September 21, 2022, 08:29:21 pm »
As it is, I discovered a bug that caused a double free if you call dispose instead of freemem because data should be set to nil after the call to freemem.
Dispose call Finalize, FreeMem not.

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Is there an error in the description of the "record"?
« Reply #19 on: September 21, 2022, 08:47:25 pm »
Indeed, so I fixed it by procedure instead of constructor. Actually it is a work-around, because calling the finalize twice - in the context of management operators - is a known issue and there is an acknowleged and still outstanding bug report for it. It is harmless except for speed. You can check the behavior with heaptrc, btw.
« Last Edit: September 21, 2022, 08:52:45 pm by Thaddy »
Specialize a type, not a var.

 

TinyPortal © 2005-2018