Освобождение памяти пр удалении компонентов
Имеется форма, на ней динамически создаются несколько GroupBox`ов(v_GroupBox:=TGroupBox.Create(MainForm);)
В этих групбоксах динамически создаются визуальные компоненты (чекбоксы, эдиты, бевелы) аналогичным образом (v_CheckBox:=TCheckBox.Create(GroupBox);)
Далее выполняем следующее:
for i:=0 to PanelForVisualisation.ComponentCount -1 do begin
PanelForVisualisation.Components[0].Free;
end;
данный код удалит групбоксы v_GroupBox
Вопрос: удаляются ли ФИЗИЧЕСКИ объекты принадлежащие v_GroupBox или нет?
То есть, если я удаляю некий компонент, то удалаяются ли компоненты родителем которых он является?
Пробую вешать на кнопку код, который удаляет подобным вышеописанным образом родительские групбоксы (то, что внутри групбоксов явно не удаляется), потом создает
снова групбоксы с наполнением. В итоге (судя по TaskManager) используемая память увеличивается.
Free уничтожает компонент, но его нужно обнулить (nil), чтобы освободить память из-под уничтоженного объекта.
Т.е.
PanelForVisualisation.Components[0] := nil;
Либо есть уже готовое движение FreeAndNil(PanelForVisualisation.Components[0]);
Но обязательно проверяй на исключение, ибо если вдуг что - будет большая порча... )))
То есть, если я удаляю некий компонент, то удалаяются ли компоненты родителем которых он является?
Удаляются. Если правильно прописан owner (в конструкторе), то при его удалении все принадлежащие ему объекты также должны удалиться.
снова групбоксы с наполнением. В итоге (судя по TaskManager) используемая память увеличивается.
Это ни о чем не говорит. Вполне возможно, что это особенность работы менеджера кучи. Либо косяк при создании объектов.
Вообще надо смотреть, постоянна ли такая тенденция к увеличению занимаемой памяти.
Кроме того, в последних версиях Delphi в одном из модулей есть переменная, позволяющая включить отслеживание утечек памяти при завершении работы программы (сейчас припомнить, что за переменная, к сожалению не могу - знающие люди, подскажите).
Вопрос: удаляются ли ФИЗИЧЕСКИ объекты принадлежащие v_GroupBox или нет?
То есть, если я удаляю некий компонент, то удалаяются ли компоненты родителем которых он является?
Не стоит путать родителя и владельца (Parent и Onwer). Как уже было сказано, контрол удалится при удалении владеющего им компонента только если у него правильно проставлен Owner.
v_Label:=TLabel.Create(v_GroupBox);
v_Label.Parent:=v_GroupBox;
то есть и овнер и парент заданы и это удаляемый родительский v_GroupBox
PanelForVisualisation.Components[0] := nil;
Так не проходит. "PanelForVisualisation.Components[0] := nil" вываливается с ошибкой "Cannot assign to a read-only property".
Вызов "FreeAndNil(PanelForVisualisation.Components[0])" завершается ошибкой "Constant object cannot be passed as var parameter". Как это обойти я так и не нашел. Кто-нибудь знает как решить сложившуюся ситуацию?
Тут всегда надо писать 0. Это связано с тем, что когда я в цикле произвожу удаление
for i:=0 to PanelForVisualisation.ComponentCount -1 do begin
PanelForVisualisation.Components[0].Free;
end;
То грубо говоря iтых компонентов нету, так как они удаляются, можно всегда уничтожать нулевой и таким образом вс удалятся.
У меня вопрос более строго характера). ранбше я всегда на все далал Free, на важно компонент переменная и т.д. На сколько это верно? Дорстаточно ли этого? или требуется обязаптельно писать = nil?
Все зависит от того, как потом будет использована переменная-ссылка на объект. Если, скажем, где-то еще также есть вызов Free, то в случае с необнуленной ссылкой получиться AV (в лучшем случае), поскольку ссылка указывает на мусор. Если же вызвать Free для ссылки = nil, то ничего не произойдет :) Просто Free устроен примерно следущим образом:
begin
if Self <> nil then Self.Delete;
end;
Впрочем, чем гадать, можно просто посмотреть под отладчиком в пошаговом режиме, что на самом деле происходит ;)