Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.06.28;
Скачать: CL | DM;

Вниз

Когда освободиться 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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.013 c
2-1241089539
Franzy
2009-04-30 15:05
2009.06.28
Абсолютно необъяснимый глюк


15-1240259891
Юрий
2009-04-21 00:38
2009.06.28
С днем рождения ! 21 апреля 2009 вторник


4-1211954383
TForumHelp
2008-05-28 09:59
2009.06.28
Навигация по MainMenu чужого приложения


3-1222849323
Александр999
2008-10-01 12:22
2009.06.28
Проверка на существование БД перед запуском приложения


2-1241715270
Forsted
2009-05-07 20:54
2009.06.28
сброс таймера