Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Результат функции - ссылка или значение? если результат функции TStringList 
V
    Опции темы
Ibragim
Дата 17.12.2006, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Вечер добрый.
Вот появился следующий вопросик.

Есть функция 

Код

function F: TStringList;
var
    Res: TStringList;
begin
    Res := TStringList.Create;
    Res.Lines.Add('Test');
    Result := Res;
end;


Потом если я пишу

Код

var
   a: TStringList;
begin
  a := TStringList.Create;
  a := F;
  Memo1.Lines.Add(a.Strings[0]);

  

то все на вид работает. Но вот впрос - не опасен ли такой код?
На С++ например в данном случае передача прошла бы только указателя на Res, а сама Res локальная, в функции F. Поэтому даже если мы бы и получили 'Test' на выходе - это говорило бы только о том, что память, ранее использованная под Res еще не освободилась.

В связи с этим вопрос:
При   a := F;  происходит КОПИРОВАНИЕ всего содержимого объектов, или только присвоение указателей?

PM MAIL   Вверх
aktuba
Дата 17.12.2006, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Происходит присвоение УКАЗАТЕЛЯ, а тот объем памяти, который занимал TStringList до этого - теряется, т.е. происходит утечка памяти. В функции у тебя происходит выделение памяти для класса и присвоение результату функции указателя на этот выделенный объем. Таким образом - такой вариант кода НЕВЕРЕН.


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Snowy
Дата 17.12.2006, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Естественно происходит присвоение указателя.
А вот создавать a совсем не нужно - ты его создаёшь функцией.
Если убрать создание вне функции и добавить уничтожение после использования - вот тогда будет верно.
Код

var
   a: TStringList;
begin
  a := TStringList.Create; // вот это нужно убрать
  a := F; // лист создаётся в функции и возвращается сюда.
  Memo1.Lines.Add(a.Strings[0]);
  // а тут нужно его уничтожить, если он больше не нужен.

А вообще правильнее делать не так.
Нужно создать лист самому, отдать его процедуре на заполнение и потом с ним работать и уничтожить.
Создавать лист в функции не хорошо - код хуже читается - при просмотре не очевидно, где он создан.
PM MAIL   Вверх
Ibragim
Дата 17.12.2006, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Ок, что общественность скажет по поводу такого кода?


Код

procedure FindForms(SiteContent: string; var FormsList: TStringList);
begin

  try
    FormsList.Clear;
  except
    FormsList := TStringList.Create;
  end;



По задумке должно если объект FormsList еще не создан, создавать. На первый взгляд так и получается. Нет подводных камней?

PM MAIL   Вверх
Bose
Дата 17.12.2006, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



Цитата(Ibragim @  17.12.2006,  17:27 Найти цитируемый пост)

Код

var   a: TStringList;
begin
  a := TStringList.Create;
  a := F;
  Memo1.Lines.Add(a.Strings[0]);


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

Код

 a := TStringList.Create;

создаёт объект TStringList и присваивает указатель на него пременной a

а строка 
Код

  a := F;

создаёт ещё один объект TStringList и присваивает указатель на него пременной a, перезаписав указатель на предыдущий объект.

если я ошибаюсь, прошу меня поправить.


Цитата(Ibragim @  17.12.2006,  19:29 Найти цитируемый пост)

задумке должно если объект FormsList еще не создан, создавать. На первый взгляд так и получается. Нет подводных камней?

в принципе так и получается. Но если вдруг исключение возникнет не из-за того, что FormsList не существует, а по какой-либо другой причине(невероятное предположение), то может произойти утечка памяти. 

если бы это писал я, то писал бы так:
Код

  if not assigned(FormsList) then FormsList:=TStringList.create;
  FormsList.clear;

PM MAIL WWW Skype   Вверх
aktuba
Дата 17.12.2006, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Правильнее так:

Код

procedure FindForms(SiteContent: string; var FormsList: TStringList);
begin
  if not Assigned(FormList) then FormList := TStringList.Create;
  FormList.Clear;
end;


Но и этот вариант не самый правильный. Самое правильное следующее:

Код

...
var
  lForms: TStringList;
...
  lForms := TStringList.Create;
  try
    FindForms('', lForms);
    ...что-то делаем с lForms...
  finally
    lForms.Free;
  end;
...
procedure FindForms(SiteContent: string; var FormsList: TStringList);
begin
  if not Assigned(FormList) then
    begin
      Alert(что-то!!!);
      Exit;
    end;
  FormList.Clear;
end;
...



--------------------
user posted image
PM MAIL WWW Skype   Вверх
Ibragim
Дата 18.12.2006, 01:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



ОК. Спасибо. Все понятно, вопрос закрыт.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0538 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.