Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.06.28;
Скачать: [xml.tar.bz2];

Вниз

Когда освободиться TStrings ?   Найти похожие ветки 

 
Альф   (2009-05-13 10:40) [0]

Простите за немножко дурацкий вопрос :)

Ситуация такая - есть функция вида

function CreateStringList(const Value: string): TStrings;
var
 i: integer;
begin
 result := TStringList.Create();
 try
// Тут заполняем список в зависимости от условий
     for i := 0 to 9 do result.Append(IntToStr(i));
 except
   result.Free();
   raise;
 end;
end;


При таком вызове понятно когда создастся и освободиться список из CreateStringList

var
 sl: TStrings;
begin
 sl := CreateStringList("*.txt");
 Memo.Lines.Assign(sl);
 sl.Free();
end;


А вот когда освободиться этот список при таком вызове ?

 Memo.Lines.Assign(CreateStringList("*.txt");


 
Григорьев Антон ©   (2009-05-13 10:42) [1]


> А вот когда освободиться этот список при таком вызове ?

При завершении программы. Да и то деструктор так и не будет вызван.


 
Palladin ©   (2009-05-13 10:44) [2]

Никак.


 
Альф   (2009-05-13 11:01) [3]

Т.е. список "уходит в закат" и компилятор, получается, никак не отслеживает такие ситуации...


 
oldman ©   (2009-05-13 11:05) [4]


> Альф   (13.05.09 11:01) [3]
> и компилятор, получается, никак не отслеживает такие ситуации...


А оно ему надо?


 
Palladin ©   (2009-05-13 11:09) [5]

Каким образом он должен это делать? Хотя конечно, можно поступить и так:

Procedure lw(Const s:String);
Begin
 Form1.Memo1.Lines.Add(s);
 Application.ProcessMessages;
End;

Type
IStrings=Interface
 Function GetStrings:TStrings;
End;

Type
 TStringsIfc=Class(TInterfacedObject,IStrings)
  Private
   m_theSL:TStringList;
  Public
   Constructor Create;
   Destructor Destroy; Override;

   Function GetStrings:TStrings;
 End;

Function TStringsIfc.GetStrings;
Begin
 Result:=m_theSL;
End;

Constructor TStringsIfc.Create;
Begin
 lw("Constructor TStringsIfc.Create");
 m_theSL:=TStringList.Create;
End;

Destructor TStringsIfc.Destroy;
Begin
 lw("Destructor TStringsIfc.Destroy");
 m_theSL.Free;
End;

Function CreateStrings:IStrings;
Begin
 Result:=TStringsIfc.Create;
 With Result.GetStrings Do
  Begin
   Add("1");
   Add("2");
  End;
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
 lw("button click in");
 Memo2.Lines.AddStrings(CreateStrings.GetStrings);
 lw("button click out");
end;


 
Григорьев Антон ©   (2009-05-13 11:15) [6]


> Альф   (13.05.09 11:01) [3]
> Т.е. список "уходит в закат" и компилятор, получается, никак
> не отслеживает такие ситуации...

Менеджер памяти, который используется, начиная с BDS2006, отслеживает. Можно получить отчёт о неосвобождённой памяти после завершения программы.


 
Альф   (2009-05-13 11:24) [7]

Спасибо


 
Альф   (2009-05-13 11:34) [8]


> Palladin ©   (13.05.09 11:09) [5]
> Каким образом он должен это делать? Хотя конечно, можно поступить и так:

Думаю можно было бы при нормальном завершении программы проверять созданные объекты и вызывать Free для неосвобождённых.

> Григорьев Антон ©   (13.05.09 11:15) [6]
> Менеджер памяти, который используется, начиная с BDS2006, отслеживает. Можно получить отчёт о неосвобождённой памяти после завершения программы.

Больше интересовала не память, а именно правильное освобождение объекта.


 
Anatoly Podgoretsky ©   (2009-05-13 11:43) [9]

Можно так
s :=  CreateStringList("*.txt");
s :=  Memo.Lines.Assign(S);
s.Free

или
Memo.Lines := CreateStringList("*.txt");
Только надо проверить по генофонду, освобождается ли старый список при присваивание, иначе вручную освободить.


 
Palladin ©   (2009-05-13 11:45) [10]


> Думаю можно было бы при нормальном завершении программы

При нормально завершении программы освободится все и твой лист не останется. Даже если ты потерял ссылку. За это не волнуйся.


 
Альф   (2009-05-13 11:52) [11]


> Anatoly Podgoretsky ©   (13.05.09 11:43) [9]
> Только надо проверить по генофонду, освобождается ли старый список при присваивание, иначе вручную освободить.

По генофонду не освобождается - там просто копирование строк из источника в приёмник.


> Palladin ©   (13.05.09 11:45) [10]
> При нормально завершении программы освободится все и твой лист не останется. Даже если ты потерял ссылку. За это не волнуйся.


Дело вот в чём:

> Григорьев Антон ©   (13.05.09 10:42) [1]
> Да и то деструктор так и не будет вызван.

Думаю это более важно.


 
Palladin ©   (2009-05-13 11:55) [12]

И что что не будет вызван? Что дальше то?


 
Anatoly Podgoretsky ©   (2009-05-13 12:02) [13]

> Альф  (13.05.2009 11:52:11)  [11]

Никакого копирования строк нет, это просто присвоение указателя


 
Альф   (2009-05-13 12:29) [14]


> Palladin ©   (13.05.09 11:55) [12]
> И что что не будет вызван? Что дальше то?

Да уже ничего :) безполезно мерять температуру у трупа :)
Думал - можно ли этот принцип, кроме списка строк, распространить на другие классы.


> Anatoly Podgoretsky ©   (13.05.09 12:02) [13]
> Никакого копирования строк нет, это просто присвоение указателя

Так то оно так - но

procedure TCustomMemo.SetLines(Value: TStrings);
begin
 FLines.Assign(Value);
end;

затем

procedure TStrings.Assign(Source: TPersistent);
...
     AddStrings(TStrings(Source));
...
end;

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


 
Palladin ©   (2009-05-13 12:31) [15]


> Альф   (13.05.09 12:29) [14]
> Думал - можно ли этот принцип, кроме списка строк, распространить
> на другие классы.

Конечно. Если не устанешь обертки писать )


 
Игорь Шевченко ©   (2009-05-13 12:31) [16]

Альф   (13.05.09 12:29) [14]

Строки - управляемый тип, в отличие от классов.


 
Альф   (2009-05-13 12:45) [17]


> Игорь Шевченко ©   (13.05.09 12:31) [16]
> Альф   (13.05.09 12:29) [14]
> Строки - управляемый тип, в отличие от классов.

Я немножко не об этом.

Вот есть класс TStringList, деструктор которого освобождает список строк в памяти. Т.е. вызов/невызов TStringList.Free() при завершении программы некритичен.

Но припустим есть наследник TStringList, который будет создавать временный файл на диске, и удалять его в деструкторе. Т.е. при невызове нового Free() файл так и останется.


 
Anatoly Podgoretsky ©   (2009-05-13 13:07) [18]

> Альф  (13.05.2009 12:29:14)  [14]

не надо выдумывать за меня, я говорил только про :=


 
Альф   (2009-05-13 14:12) [19]


> Anatoly Podgoretsky ©   (13.05.09 13:07) [18]
> не надо выдумывать за меня, я говорил только про :=

Так а я о чём :)


 
Игорь Шевченко ©   (2009-05-13 14:33) [20]


> Но припустим есть наследник TStringList, который будет создавать
> временный файл на диске, и удалять его в деструкторе. Т.
> е. при невызове нового Free() файл так и останется.


Даже если это будет не наследник TStringList, если деструктор не будет вызван, файл таки останется


 
Anatoly Podgoretsky ©   (2009-05-13 14:47) [21]


> Так а я о чём :)

Тогда первый вариант


 
Sapersky   (2009-05-13 14:49) [22]

Ну вот ещё вариант StringList с автоматическим освобождением:
http://edn.embarcadero.com/article/33423
В старых версиях вместо record можно использовать object.


 
Григорьев Антон ©   (2009-05-14 08:46) [23]


> Альф   (13.05.09 11:34) [8]
> Думаю можно было бы при нормальном завершении программы
> проверять созданные объекты и вызывать Free для неосвобождённых.

В имеющейся реализации - нельзя. С точки зрения менеджера памяти объект - это просто выделенный блок. Менеджер не знает, что находится в этом блоке - объект или просто данные. Поэтому, даже обнаружив утечку, не имеет возможности решить, нужно здесь вызывать Free или нет.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2009.06.28;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.005 c
11-1203187158
andreil
2008-02-16 21:39
2009.06.28
Правильное отображение рисунков в ЛистБоксе


4-1211888967
Сергей
2008-05-27 15:49
2009.06.28
Хуки


15-1240847736
Практик
2009-04-27 19:55
2009.06.28
Наука: Прикладной смысл


15-1240305165
Cobalt
2009-04-21 13:12
2009.06.28
Лицензионность винды


15-1240433713
Юрий
2009-04-23 00:55
2009.06.28
С днем рождения ! 23 апреля 2009 четверг





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский