Удаление TList из TList

Я пытаюсь освободить Tlist в Tlist в событии onDestroy, и FastMM4 вызывает ошибку нарушения доступа. Вот фрагмент кода.

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;

Я получаю сообщение об ошибке доступа в TSignal(SignalList.items[x]). Бесплатно; линия. При освобождении элементов AlarmList перед освобождением элементов SignalList возникает ошибка нарушения доступа, но ПОЧЕМУ?

Обновление: я использую Delphi 7.0 на Windows XP. Фактические сообщения FastMM4 следующие.


FastMM обнаружил попытку вызова виртуального метода для освобожденного объекта. Расширение доступа теперь будет увеличено, чтобы прервать текущую операцию.

Класс Freed Object: TList

Виртуальный метод: уничтожить

Адрес виртуального метода:427CF0

Номер распределения был: 80055

Далее следует большой дамп памяти.


Согласно этой ошибке FastMM4, если вы освобождаете объект в другом объекте, вы также автоматически освобождаете владельца. Я знаю, что это не может быть правдой, но поправьте меня, если я ошибаюсь.

2 ответа

Решение

Есть ли TSignal не свободен его AlarmList член в своем деструкторе? (Вот как бы я это сделал).

Обновление: это работает, если вы удалите TSignal(SignalList.Items[x]).AlarmList.Free; линия?

Второе обновление: каждый TListПредметы нужно освобождать, если они содержат указатели на объекты.

Ваша проблема была в том, что TSignal это не TList, Так как он заботится об освобождении своих членов (таких как Alarmlist), этот Alarmlist не должен освобождаться явно.

Поскольку TAlam и TSignal являются объектами (а не записями), я считаю, что вы должны использовать TObjectList вместо TList. TObjectList имеет специальное свойство calld OwnsObjects, которое позволяет ему правильно освобождать содержимое по мере его освобождения. Проверьте это http://docwiki.embarcadero.com/VCL/XE/en/Contnrs.TObjectList.OwnsObjects

В качестве совета не используйте TList, если вам не нужно хранить указатели, а не объекты.

Другие вопросы по тегам