Удаление 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, если вам не нужно хранить указатели, а не объекты.