The DataCAD Developer Network (DDN) is an online resource for information and support for DCAL® (DataCAD Applications Language) developers as well as anyone interested in creating fonts, toolbars, hatch patterns, or linetypes for use in DataCAD.

Moderator: pjdixit

#75660 by dhs
Fri Feb 08, 2019 2:06 am
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.
#75664 by Mark F. Madura
Fri Feb 08, 2019 2:00 pm
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
#75665 by dhs
Fri Feb 08, 2019 2:56 pm
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.

Who is online

Users browsing this forum: No registered users and 3 guests

About DataCAD Forum

The DataCAD Forum is a FREE online community we provide to enhance your experience with DataCAD.

We hope you'll visit often to get answers, share ideas, and interact with other DataCAD users around the world.

DataCAD

Software for AEC Professionals Since 1984