Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Ошибка работы с памятью после удаления контролов


Автор: Beltar 20.1.2017, 16:02
В общем дано, наследник TImage, который при рождении сразу еще создает пару подписей.

Код

constructor TLabeledImage.Create(AOwner, AParent: TWinControl;
  ALeft, ATop, AWidth, AHeight: Integer);
begin
inherited Create(AOwner) ;
Parent:=AParent;
DragMode:=dmAutomatic;

FLabel1:=TLabel.Create(AOwner);
FLabel1.Parent:=AParent;
FLabel2:=TLabel.Create(AOwner);
FLabel2.Parent:=AParent;
//Помимо этого задаются еще всякие Left, Width, значения по умолчанию и т. п.
end;


Т. е. метки передаются во владение и родительство тому же контролу, что и сама картинка.

Справка и несколько просмотренных перед этим топиков инете подсказывают, что для удаления объектов из Components владельца нужно занилять им Parent. Соответственно для убиения.

Код

destructor Destroy;override;
//...
destructor TLabeledImage.Destroy;
begin
if Assigned(FLabel1) then
  begin
  FLabel1.Parent:=nil;
  FLabel1.Free;
  end;
if Assigned(FLabel2) then
  begin
  FLabel2.Parent:=nil;
  FLabel2.Free;
  end;
  inherited;
end;


Сам контрол

Код

procedure TfmMain.acObjDeleteExecute(Sender: TObject);
begin
if SelPicture=nil then Exit;//Удаляю контрол под мышкой.
SelPicture.Parent:=nil;
SelPicture.Free;
end;


3 Контрола из Controls у родителя благополучно исчезают, но при завершении программы вылетает Invalid Pointer Operation, нехороший симптом.
Что я делаю не так?

Автор: kami 20.1.2017, 18:48
acObjDeleteExecute - что приводит к вызову этого метода? Не "внутренности" TLabeledImage случайно?

Автор: Beltar 23.1.2017, 17:01
Цитата

acObjDeleteExecute


Нет, это банальное выполнение акшена acObjDelete.

Попробовал просто бросить что-то на форму и удалить.

Код

Image1.Parent:=nil;
FreeAndNil(Image1);


Удаляется, но при завершении программы та же ошибка, как и при прямом вызове RemoveControl у родителя.

Автор: Doga 31.1.2017, 17:30
Привет.

При динамическом создании компонента, попробуйте в качестве аргумента конструктора AOwner использовать значение NIL.

Автор: Beltar 1.2.2017, 13:45
То же самое. У меня получается, что ошибка возникает из-за FLabel1.Free; и FLabel2.Free;
С точки зрения уничтожения всего после завершения работы программы, оно будет пофигу. Но если я убираю лейблы из Controls владельца, то они, по идее, просто повисают где-то, т. е. получается утечка. Почему я не могу после этого сделать им Free мне непонятно.

Есть правда, вариант, забить на утечку (редактор с удалением элементов мне нужен, не конечному пользователю), но понять все-таки хотелось бы.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)