Page 1 of 1

D4D Garbage Collection

PostPosted: Fri Feb 08, 2019 2:06 am
by dhs
Hi,

The code of a macro I am working on creates a number of TList collections of records when the macro starts. The TList variables are declared in the pl^ record, but as the TList is basically a list of pointers I believe the elements will not actually reside within the memory allocated by the SetLocalSize call. I believe that Delphi does not have automated garbage collection so expect that I need to explicitly free them (??)

A a result I have added the cleanup code is shown below:
Code: Select allPROCEDURE Cleanup;
VAR
  CatDef : CategoryDef;
BEGIN
  if assigned (l^.Categories) and (l^.Categories.Count > 0) then begin
    for CatDef in l^.Categories do
      if assigned (CatDef.Custom) and (CatDef.Custom.Count > 0) then
        CatDef.Custom.Free;
    l^.Categories.Free;
  end;
  if assigned(l^.UserFields) and (l^.UserFields.Count > 0) then
    l^.UserFields.Free;
END;


I am calling the above procedure from the logic that happens when the user presses S0 to exit the macro, and also in the Main function when result is set to XDone. The S0 logic is getting called and processed correctly as expected. The logic in Main function has not been called in my testing (which doesn't particularly surprise me as I guess it is there to handle unexpected conditions ??)

BUT when the user exits the macro by using shortcut keys such as 'm' (move), the cleanup proc is not being called. I fear it will create a memory leak if it is not called. Can anybody (Dave ??) advise me on where I can place the cleanup code so that it will be called in all situations where the macro exits?

As a side question, I placed the assigned and count tests in my Cleanup proc as in an earlier version it was sometimes getting called twice. I have now fixed that problem (getting called twice), but have left the tests in. From what I read on the net I expected that the assigned test would have been adequate, but needed to add the count test to prevent free being called again (with a resulting exception). I am wondering if anybody can throw any light on the best way to test if the variables have already been freed.

Thanks,
David H.

Re: D4D Garbage Collection

PostPosted: Fri Feb 08, 2019 2:00 pm
by Mark F. Madura
Code: Select all  { Section 4: Alast - If your macro has been interrupted by user action }
  else if act = Alast then begin
    // If you're going to get blown off the stack...
    // (i.e.) the user pressed a hotkey,
    // then this is your last chance to clean up temporary data.
  end

Re: D4D Garbage Collection

PostPosted: Fri Feb 08, 2019 2:56 pm
by dhs
Thank you Mark!

I was hoping there was a simple answer! I should have noticed this, but most of my D4D knowledge comes from looking at the samples and the only one that uses ALast is the AEC_Model sample (and looking at its use there I'm not even sure that it is necessary in that macro!)
... should have read Joe's tutorials (and a couple of posts where he asked questions whilst writing the tutorials)!

I have added the ALast test and my cleanup code is now being called exactly when I want it to be.

David H.