Recent

Author Topic: Destructing object whose private variables are of dynamic types  (Read 782 times)

AlexanderK

  • Newbie
  • Posts: 6
Hello! A newbie here.
This is a simplified example of a class taken from a book from 2013.
'TPerson' class has two private variables 'FAwards' of array type and 'FName' of 'ansistring' type (because of '{$H+}'). Both types are considered dynamic and managed on the heap.
Now, in the original code of the class the implementation of the destructor was without 'SetLength(FName,0);'.
To my understanding, both  'FAwards' and 'FName' are dynamic and managed on the heap and both should be released upon destruction. According to 'SetLength' documentation, "If Zero is specified, the array is cleared and removed from memory."
Should both types be set to zero to properly destruct the instance of the class or 'ansistring' types could be skipped?

Code: Pascal  [Select][+][-]
  1. program person_class;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. type
  6.   TPerson = class
  7.     FAwards: array of string;
  8.     FName: string;
  9.  
  10.     constructor create(aName: string);
  11.     destructor destroy; override;
  12.     procedure displayInfo;
  13.  
  14.     property name: string read FName;
  15.   end;
  16.  
  17.  
  18. constructor TPerson.create(aName: string);
  19.   begin
  20.     inherited Create;
  21.     FName := aName;
  22.   end;
  23.  
  24. destructor TPerson.destroy;
  25.   begin
  26.     SetLength(FAwards,0);
  27.     SetLength(FName,0); // Should be set to zero just as 'FAwards'?
  28.     inherited Destroy;
  29.   end;
  30.  
  31. procedure TPerson.displayInfo;
  32.   begin
  33.     WriteLn('Person name: ',name);
  34.   end;
  35.  
  36. var person: TPerson;
  37.  
  38. begin
  39.   person:= TPerson.create('John Smith');
  40.   person.displayInfo;
  41.   person.Free;
  42.  
  43.   {$IfDef WINDOWS}
  44.   ReadLn;
  45.   {$EndIf}
  46. end.
  47.  

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • Debugger - SynEdit - and more
    • wiki
Re: Destructing object whose private variables are of dynamic types
« Reply #1 on: June 12, 2025, 08:02:57 pm »
There may be a debate on "coding style" or even personal preference....

Going for technical only: You don't need to set them to length zero. This will be done.

You can compile your app with Heaptrc -gh (on the debugger page of project options), and then when it ends it will give you a message.
Part of that message should be "0 unfreed blocks" (or very similar)





Note, if you use "pointer to records" and then allocate mem for them, this may differ.

IIRC (but need to check) dispose, should deal with it, but if you use AllocMem and FreeMem directly, and then assign the memory to a pointer to record, containing an ansistring => then that string is not taken care off.
« Last Edit: June 12, 2025, 08:04:42 pm by Martin_fr »

AlexanderK

  • Newbie
  • Posts: 6
Re: Destructing object whose private variables are of dynamic types
« Reply #2 on: June 12, 2025, 09:11:54 pm »
In relation to 'Heaptrc -gh'. I ticked the option but the only output I see in the console window is the expected result from of the program. Attached the screenshots with the output and Debugging settings. Do I miss something?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • Debugger - SynEdit - and more
    • wiki
Re: Destructing object whose private variables are of dynamic types
« Reply #3 on: June 12, 2025, 09:24:51 pm »
I don't see a prompt on your console, so I guess the program is still running?

Heaptrc only reports when the program exits for good.

It should then print
Code: Text  [Select][+][-]
  1. Heap dump by heaptrc unit of "project1.exe"
  2. 0 memory blocks allocated : 0/0
  3. 0 memory blocks freed     : 0/0
  4. 0 unfreed memory blocks : 0
  5. True heap size : 65536 (192 used in System startup)
  6. True free heap : 65344

The non-zero numbers can vary. The "unfreed" should be zero.

AlexanderK

  • Newbie
  • Posts: 6
Re: Destructing object whose private variables are of dynamic types
« Reply #4 on: June 12, 2025, 09:46:55 pm »
You're right. The program is still running. In the screenshot I attached before, the program stopped after {$IfDef WINDOWS} at ReadLn and awaits [Enter] key to finish, but when I press [Enter] the window closes so I'm unable to see the heaptrc report.
On Windows I have to add {$IfDef WINDOWS} ReadLn; {$EndIf} at the end. Otherwise, the console window immediately closes after execution. Any remedy to this? Maybe the report is being saved to a file somewhere?

P.S. Understood about the heaptrc report. Thank you!

lainz

  • Hero Member
  • *****
  • Posts: 4725
  • Web, Desktop & Android developer
    • https://lainz.github.io/
Re: Destructing object whose private variables are of dynamic types
« Reply #5 on: June 12, 2025, 09:52:17 pm »
Run a cmd Window. (Windows Key + R, type cmd). Go to the folder where your exe is.

CD "C:\mydir"

And run from there, the command window will not close.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • Debugger - SynEdit - and more
    • wiki

AlexanderK

  • Newbie
  • Posts: 6
Re: Destructing object whose private variables are of dynamic types
« Reply #7 on: June 12, 2025, 10:21:06 pm »
Running it from within cmd works. I see the report now.
Appreciate your help.
Thank you!

P.S. Noted about the environment link.

 

TinyPortal © 2005-2018