Работа с объектами в Delphi требует понимания того, как в этом языке программирования осуществляется передача ссылок. В частности, важно понимать, что объекты в Delphi являются ссылкотипными, и ссылки на эти объекты передаются по значению. Это означает, что при передаче объекта в функцию или процедуру вы получаете копию ссылки, а не самого объекта.
Проблема:
В коде ниже наблюдается типичная ошибка, связанная с передачей ссылок:
procedure TMainForm.GetNodeListByClass(const ClassName: string; outputList: TStringList);
var
foundNode: TDomTreeNode;
foundNodesList: TStringList;
begin
foundNodesList := TStringList.Create;
try
foundNode := NodeFindNodeByClassName(DomTree.RootNode, ClassName);
if Assigned(foundNode) then
GetNodeList(foundNode, foundNodesList);
outputList := foundNodesList;
finally
FreeAndNil(foundNodesList);
end;
end;
Проблема заключается в том, что после строки outputList := foundNodesList; обе переменные указывают на один и тот же объект TStringList. После вызова FreeAndNil(foundNodesList); происходит освобождение памяти, на которую указывает foundNodesList, и так как outputList также указывает на этот объект, он становится невалидной ссылкой.
Решение:
Чтобы решить эту проблему, достаточно явно заполнить список outputList, передаваемый в функцию, и убрать создание временного списка foundNodesList:
procedure TMainForm.GetNodeListByClass(const ClassName: string; outputList: TStringList);
var
foundNode: TDomTreeNode;
begin
outputList.Clear;
foundNode := NodeFindNodeByClassName(DomTree.RootNode, ClassName);
if Assigned(foundNode) then
GetNodeList(foundNode, outputList);
end;
Таким образом, временный список становится не нужен, и утечка памяти предотвращается.
Важные замечания:
Всегда используйте блоки try..finally для защиты объектов и предотвращения утечек памяти.
Если список outputList должен быть очищен перед заполнением, добавьте outputList.Clear перед заполнением списка.
Использование FreeAndNil не требуется, если переменная, на которую указывает ссылка, выходит из области видимости после освобождения объекта.
Понимание этих принципов поможет избежать ошибок, связанных с утечками памяти и некорректным управлением объектами в Delphi.
В Delphi при работе с объектами важно понимать, как передача ссылок может привести к утечкам памяти, и какие существуют решения для их избежания.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS