Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

как правильно очистить TList'ы, чтобы не было утечек памяти


Страницы:   1 2

__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) нужно только один раз.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо