0
votes

I am trying to free Tlist within a Tlist in a onDestroy event and FastMM4 is raising an access violation error. Here is the code snippet.

procedure TSignalFrm.FormDestroy(Sender: TObject);
var
  x,y: integer;
begin
  for x := 0 to signalList.Count - 1 do
  begin
    for y:=0 to TSignal(SignalList.Items[x]).alarmList.Count-1 do
    begin
      TAlarm(TSignal(SignalList.Items[x]).alarmList.Items[y]).Free;
    end;
    TSignal(SignalList.Items[x]).AlarmList.Free;
    TSignal(SignalList.Items[x]).Free;
  end;
  SignalList.Free;
end;

I get access violation error at TSignal(SignalList.items[x]).Free; line. Freeing AlarmList items before freeing SignalList items raises the access violation error, but WHY?

Update: I am using Delphi 7.0 on Windows XP. The actual FastMM4 messages is as follows.


FastMM has detected an attempt to call a virtual method on a freed object. An access viloation will now be raised in order to abort the current operation.

Freed Object class: TList

Virtual method: Destroy

Virtual method address:427CF0

The allocation number was: 80055

Followed by a lots of memory dump.


According to this FastMM4 error, if you free an object within an another object, you automatically free the owner as well. I know that can't be true, but correct me if I am wrong.

2
What version of Delphi are you using?M.Sameer
"FastMM4 is raising an access violation error" and "I get access violation error" give no information. What's the exact error message (including any memory addresses)? Even though we can probably guess what they are, you get better and quicker answers when we don't have to do so. Also, as @M.Sameer said, knowing which Delphi version would help.Ken White
The code for the TSignal and TAlarm constructors/destructors could help as well and any code used to add/remove alarms to/from a signal.Marjan Venema

2 Answers

5
votes

Does TSignal not free its AlarmList member in its destructor? (That’s how I would do this).

Update: does it work if you remove the TSignal(SignalList.Items[x]).AlarmList.Free; line?

Second update: Each TList's items need to be freed, if it contains pointers to objects.

Your problem was that TSignal is not a TList. Since it takes care of freeing its members (such as the Alarmlist), that Alarmlist should not be freed explicitly.

2
votes

Since TAlam and TSignal are both objects (not records) I believe you should use TObjectList instead of TList. TObjectList has a special property calld OwnsObjects that allows it to free it's contents properly as it is being freed. Check this out http://docwiki.embarcadero.com/VCL/XE/en/Contnrs.TObjectList.OwnsObjects

As an advice do not use TList unless you need to store pointers not objects.