![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
как правильно очистить TList'ы, чтобы не было утечек памяти
__QWERTY © (2012-05-04 14:28:00)
var
I: Integer;
ListA, ListB: TList;
SL: TStringList;
begin
ListA := nil;
ListB := nil;
try
ListA := TList.Create;
ListB := TList.Create;
SL := TStringList.Create;
ListA.Add(SL);
for I := 1 to 10 do
begin
SL := TStringList.Create;
ListA.Add(SL);
ListB.Add(SL);
end;
except
ListA.Free;
ListB.Free;
end;
end;
Anatoly Podgoretsky (2012-05-07 18:43:00) [1]
> MsGuns © (07.05.12 10:47) [21]
А веб сервер уже предлагали?
Давайте будем жрать! (2012-05-07 17:01:00) [2]
> все надели "мудрое выражение ица" и принялись советовать
Дык «Начинающим» не для просвещения начинающих существует, а для куражу бывалых. %-)
Inovet (2012-05-07 15:07:00) [3]> [21] MsGuns © (07.05.12 10:47)
> Как это все по-мастаковски :)
Как вычистить глистов, типа?:)
MsGuns (2012-05-07 10:47:00) [4]Огурец написал от балды чушь и тут же все надели "мудрое выражение ица" и принялись советовать.
Кое-кто предложил даже интерфейс сваять. Угу, а сбоку еще ком-сервер и уракакл впридачу.
Как это все по-мастаковски :)
Давайте будем жрать! (2012-05-05 12:28:00) [5]Понятно :-)
AV (2012-05-05 12:21:00) [6]>>Это зачем? Чем TList.IndexOf() не угодил?
>> А явное приведение типов зачем?
можно и IndexOf, можно и не приводить
Но мне так понятнее.
Давайте будем жрать! (2012-05-05 12:12:00) [7]
> procedure AddStringListToListForKill(SL:Pointer);
Это зачем? Чем TList.IndexOf() не угодил?
> Pointer(L.Items[i])
А явное приведение типов зачем?
AV (2012-05-05 11:41:00) [8]а-ля так
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
ListA := TList.Create;
ListB := TList.Create;
SL := TStringList.Create;
ListA.Add(SL);
for I := 1 to 2 do
begin
SL := TStringList.Create;
ListA.Add(SL);
ListB.Add(SL);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
procedure AddStringListToListForKill(SL:Pointer);
var
i: Integer;
Uniq: Boolean;
begin
Uniq := True;
for i := 0 to ListC.Count - 1 do
begin
if Pointer(ListC.Items[i]) = SL then
begin
Uniq := False;
Break;
end;
end;
if Uniq then
ListC.Add(TStringList(SL));
end;
procedure PrepareToFreeList(L: TList);
var
i: Integer;
begin
for i := 0 to L.Count - 1 do
begin
AddStringListToListForKill(Pointer(L.Items[i]));
end;
end;
begin
ListC := TList.Create;
PrepareToFreeList(ListA);
PrepareToFreeList(ListB);
for i := 0 to ListC.Count - 1 do
begin
TStringList(ListC.Items[i]).Free;
end;
end;
icWasya (2012-05-05 09:47:00) [9]Если нужно иметь именно такие списки, то есть несколько списков с произвольным добавлением/удалением, и нужно вести автоматический их учёт, то...
1) делать по технологии COM - объекты ведут учёт количества ссылок на них, и при обнулении количества ссылок автоматически вызывать деструктор.
2) делать по технологии компонент - при вызове деструктора объекта слать всем спискам уведомление, что объект уничтожился, и списки при этом должны удалить ссылку на уничтоженый объект.
3) вести полуавтоматический учёт - только один список является владельцем объектов, и при удалении из этого списка у объекта вызывается деструктор. А все остальные списки содержат только ссылки на объекты и не следят за временем их жизни. Естественно чистку первого списка делать только по окончании работы.
Ega23 (2012-05-05 09:16:00) [10]
> FreeAndNil во втором тоже нормально отработает.
Да ну?
procedure TForm18.Button1Click(Sender: TObject);
var
list1, list2: TList;
sl: TStringList;
i: Integer;
begin
list1 := TList.Create;
list2 := TList.Create;
try
sl := TStringList.Create;
sl.Text := 'sasorugoidfgpijp'#13#10'sdfjsoidfosiugfoiudbhsg';
list1.Add(sl);
list2.Add(sl);
for i := 0 to list1.Count - 1 do
begin
sl := TStringList(list1[i]);
FreeAndNil(sl);
end;
for i := 0 to list2.Count - 1 do
begin
sl := TStringList(list2[i]);
FreeAndNil(sl);
end;
finally
list2.Free;
list1.Free;
end;
end;
Invalid pointer operation, что вообще-та ожидаемо.
Германн (2012-05-04 22:43:00) [11]
> Но если вместо FreeAndNil с оббъектами из второго списка
> попытаемся работать?
А это уже будет другой пример.
CRLF (2012-05-04 22:30:00) [12]
> Германн © (04.05.12 22:13) [12]
Он-то отработает... Но если вместо FreeAndNil с оббъектами из второго списка попытаемся работать? Последствия непредсказуемые.
Германн (2012-05-04 22:13:00) [13]
> во втором-то указатель инвалидный остался...
FreeAndNil во втором тоже нормально отработает.
Ega23 (2012-05-04 21:41:00) [14]
> после FreeAndNil нет смысла заботиться проверкой уничтожен
> объект или нет.
Сань, он один и тот же объект в два разных листа добавляет. Ну FreeAndNil в первом, во втором-то указатель инвалидный остался...
Rouse_ (2012-05-04 20:48:00) [15]после FreeAndNil нет смысла заботиться проверкой уничтожен объект или нет.
Free сам проверит на nil
Cobalt (2012-05-04 19:27:00) [16]> MBo © (04.05.12 15:41) [4]
>for i := 0 to ListA.Count - 1 do
>TObject(ListA[i]).Free;
+1
Ega23 (2012-05-04 17:55:00) [17]Написать потомка TList, перекрыть ему Notify, там FreeAndNil дел
ааа, у него один и тот же объект.. Не получится. Либо третий ObjectList держать, в котором всё сидит, либо через интерфейсы разруливать
MBo (2012-05-04 17:36:00) [18]Угу, не обратил внимания, что одни объекты в двух списках
CRLF (2012-05-04 16:54:00) [19]
> А вообще в данном случае проще TObjectList c OwnObjects
> использовать
Только рискуем нарваться на то, что в списке А объекты уже уничтожились, а в списке Б ссылки на них всё ещё живут.
icWasya (2012-05-04 16:49:00) [20]Но! Если делаете так
SL := TStringList.Create;
ListA.Add(SL);
ListB.Add(SL);
то есть заносите один объект сразу в два списка - то вызывать деструктор(Free) нужно только один раз.