Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.04.2019, 01:43   #1
Devvver
Пользователь
 
Аватар для Devvver
 
Регистрация: 30.01.2010
Сообщений: 23
Вопрос Освобождение памяти у функции при возврате класса

Есть к примеру функция
Код:
function Namefunction(my:Tstring) :Tstringlist   ;
begin
// тут берутся какие то данные из my
// и возвращаются через result:=sortLSI;
// где sortLSI экземпляр класса Stringlist 
end
Вопрос - можно ли в функции освободить sortLSI ? Если нет - то когда он освободится?
мой сайт о Таиланде https://tailand-gid.org
Devvver вне форума Ответить с цитированием
Старый 08.04.2019, 06:24   #2
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

result:=sortLSI; Тут присвоение идёт по механизму присвоение указателя указателю. Поэтому если вы освободите sortLSI, то все кто будет работать с result получат невалидные данные.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 09.04.2019, 10:36   #3
Devvver
Пользователь
 
Аватар для Devvver
 
Регистрация: 30.01.2010
Сообщений: 23
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
result:=sortLSI; Тут присвоение идёт по механизму присвоение указателя указателю. Поэтому если вы освободите sortLSI, то все кто будет работать с result получат невалидные данные.
Понятно. А если ситуация следующая - в функции я в var объявлю sortLSI , далее ее создам, можно ли потом делать так
Код:
result:=sortLSI;
sortLSI.FREE;
Это корректно?
мой сайт о Таиланде https://tailand-gid.org
Devvver вне форума Ответить с цитированием
Старый 09.04.2019, 10:44   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Нет конечно. Функция возвратит поломанный sortLSI. Освобождай после вызова функции
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 09.04.2019, 18:26   #5
Devvver
Пользователь
 
Аватар для Devvver
 
Регистрация: 30.01.2010
Сообщений: 23
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Нет конечно. Функция возвратит поломанный sortLSI. Освобождай после вызова функции
Это на 1 сообщение или на второе ответ?
мой сайт о Таиланде https://tailand-gid.org
Devvver вне форума Ответить с цитированием
Старый 10.04.2019, 07:45   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

это на фразу
Цитата:
Это корректно?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 10.04.2019, 22:57   #7
Devvver
Пользователь
 
Аватар для Devvver
 
Регистрация: 30.01.2010
Сообщений: 23
По умолчанию

Что то я запутался. Давайте на конкретном примере.
Код:
function Namefunction :Tstringlist   ;
var
SortLSI:Tstringlist;
begin
SortLSI:Tstringlist.Create;
SortLSI.Add('Новая строка');
result:=sortLSI;
end;
В обработчике событий, к примеру кнопка
Код:
procedure TForm2.add_urlClick(Sender: TObject);
var 
FSortLSI:Tstringlist;
begin
FSortLSI:=Tstringlist.Create;
FSortLSI:= Namefunction;
Memo1.lines.AddStrings(FSortLSI);
FSortLSI.free;
end;
Вопрос - в функции мы не освободили sortLSI.
В обработчике кнопки мы освободили FSortLSI, освободится ли переменная sortLSI?
Если можно - дайте ссылки где можно почитать о правилах освобождения памяти классов.
мой сайт о Таиланде https://tailand-gid.org
Devvver вне форума Ответить с цитированием
Старый 11.04.2019, 00:22   #8
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

можно сделать так
Код:
function Namefunction: Tstringlist;
begin
result:= Tstringlist.Create;
result.Add('Новая строка');
end;

procedure TForm2.add_urlClick(Sender: TObject);
begin
Memo1.lines.AddStrings(Namefunction);
end;
вы уже class строки Memo отдали, а далее по идее освобождение будет такое.
Код:
procedure TForm1.Button2Click(Sender: TObject);
begin
Memo1.lines.Delete(Memo1.lines.Count-1);
end;
Либо по всем
Код:
procedure TForm1.Button3Click(Sender: TObject);
begin
Memo1.lines.Clear;
end;

Последний раз редактировалось Aliens_wolfs; 11.04.2019 в 00:38.
Aliens_wolfs вне форума Ответить с цитированием
Старый 11.04.2019, 06:09   #9
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Вот смотри у вас Create 2 раза, а Free 1 раз. Это неправильно.
Цитата:
Сообщение от Devvver Посмотреть сообщение
FSortLSI:=Tstringlist.Create;
FSortLSI:= Namefunction;
Здесь у вас утечка памяти.
Объект вы создали и тут же заменили его указатель другим. Тем самым у вас в памяти получился объект на который не указывает ни одна переменная.

Выкинуть лишний Create и всё. Какой из 2-х решать вам. Я бы выкинул бы первый.

Если делать по уму, то следует отказаться от функций для классов. Как у любого правила у него есть исключения
- класс строитель.
- интерфейсные объекты.

В первом случает мы должны обозвать функцию как Create.
К примеру ElementCreate.

А во втором случае работает авто подсчёт ссылок и там объект на который никто не ссылается автоматически удаляется.



Код:
procedure NameAdd(var SortLSI:Tstringlist);
begin
SortLSI.Add('Новая строка');
end;


procedure TForm2.add_urlClick(Sender: TObject);
var 
FSortLSI:Tstringlist;
begin
FSortLSI:=Tstringlist.Create;
AddName(FSortLSI);
Memo1.lines.AddStrings(FSortLSI);
FSortLSI.free;
end;
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 11.04.2019, 09:29   #10
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
Вопрос - в функции мы не освободили sortLSI.
В обработчике кнопки мы освободили FSortLSI, освободится ли переменная sortLSI?
Освобождать мы будем НЕ переменную.
А объект, ссылка на который находится в данной переменной.
А также м.б. (ссылка на ЭТОТ же объект) еще в десятке других переменных.
sortLSI, FSortLSI, result --к примеру. РАзные переменные, но один и тот же объект.

НО освободить (Free) объект мы должны РОВНО один раз.
при этом(после Free) ВСЕМИ прочими ссылками(переменными) мы НЕ сможем (и не имеем права) пользоваться.
при желании(или необходимости) мы можем заменить их(значения переменных) :=nil.
Код:
result:=sortLSI;
sortLSI:=nil;FreeAndNil(sortLSI);
настоятельно рекомендуется если данная переменная существует(МОЖЕТ использоваться) и далее.
sortLSI дальше НЕ используется, так что...
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Утечка памяти [Освобождение памяти массива] denis76560 Общие вопросы Delphi 4 27.11.2016 18:20
освобождение памяти Homa_1983 Общие вопросы C/C++ 7 31.08.2013 14:36
преобразование к QString при возврате из функции exelim Общие вопросы C/C++ 1 05.08.2013 18:45
Освобождение памяти от экземпляра класса Mixim Общие вопросы .NET 8 05.01.2011 17:27
Освобождение памяти VadEr Общие вопросы Delphi 2 17.04.2009 22:23