Удаление TList из TList - PullRequest
       53

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

0 голосов
/ 25 марта 2011

Я пытаюсь освободить 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 class: TList

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

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

Номер выделения был: 80055

С последующим большим дампом памяти.


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

Ответы [ 2 ]

5 голосов
/ 25 марта 2011

Разве TSignal не освобождает свой член AlarmList в своем деструкторе? (Вот как бы я это сделал).

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

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

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

2 голосов
/ 25 марта 2011

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

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

...