Форум: "Начинающим";
Текущий архив: 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