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

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

Dispose


Страницы:   1 2

TUser ©   (2004-08-14 10:36:00) 

Пол-ночи просидел, никак не могу понять, где ошибка в таком коде

  pcat:=FCatalog;
  while pcat <> nil do begin
     pcat1:=pcat^.Next;
     pcl:=pcat^.First;
     while pcl <> nil do begin
        pcl1:=pcl^.Next;
        pch:=pcl^.First;
        while pch <> nil do begin
           pch1:=pch^.Next;
           try
            if pch^.AutoFree then // begin
            // if assigned(pch^.Control) then
               FreeAndNil(pch^.Control)
               {end} else pch^.Control:=nil;
           except
            // if Control is alreadey destroyed by user
           end;
           Dispose(pch);
           pch:=pch1;
           end;
        if assigned(pcl^.Font) then
           FreeAndNil(pcl^.Font);
        Dispose(pcl);
        pcl:=pcl1;
        end;
     Dispose(pcat);
     pcat:=pcat1;
     end;
  if assigned(FList) then
     FList.Free;

Поясню. Есть дерево из нескольких уровней, корень его - FCatalog. Я совершаю его обход и освобождаю занятую память. Там, где есть ссылки на объекты - их я дестрою. То, что память выделена, все ссылки присвоены правильно, если нет ничего - то nil, и дерево построено правильно и т.д. - это я говорю совершенно точно и уверен на 100%. С этим деревом программа работает и до тех пор, пока не начнет выполняться этот код все работает нормально. Короче говоря, нет у меня подозрений на какую-то тривиальную ошибку.

А этот код выполняется нестабильно. Иногда выполняется, иногда при возникает AV. Причем даже так - подряд какое-то количество раз все выполняется нормально, а потом вдруг начинается глюк. Много раз подряд глючит, потом опять все нормально.

Отладчик говорит, что ошибки возникают на Dispose'ах. При этом Ctrl+F7 показывает, что соотвествующий указатель куда-то указывает и там действительно лежит некоторое (причем правильное) значение. Т.е. вроде бы попытка высвободить эту память не должна привождить к ошибкам.
В чем тут может быть дело.


TUser   (2004-08-14 12:42:00) [21]

Мешает то, что на разных уровнях дерева узлы разные. Например на уровне pcl расположены PCell = ^TCell, а одним из элементов этого TCell является TFont, которого нет на других уровнях. А на самом нижнем уровне есть TControl, которого на более высоких уровнях нет. Ну и т.д.
А обход дерева таким способом - это вполне нормальное дело, тут проблема не в алгоритме обхода, а с дестроем объектов и работе с памятью. Только вот я никак не могу найти этот баг.


Sergey Kaminski   (2004-08-14 12:22:00) [22]

Например, что мещает сделать вот таким образом (пример, разумеется, схематический):


procedure DeleteRecursively (ASubNode: TMyNode);
var
 I: Integer;
begin
 for I := 0 to ASubNode.Count-1 do
 begin
   DeleteRecursively (ASubNode[I]);
 end;
 ASubNode := nil;
end;

begin
 DeleteRecursively (FCatalog); // это все :)
end.


going down recursively.... (c)
:-)


Sergey Kaminski   (2004-08-14 12:12:00) [23]

ИМХО, пытаясь анализировать _такой_ код, можно потратить пол-ГОДА.

Кажется, имеет смысл сделать обход дерева не столь причудливым образом, а просто, именно - используя рекурсивный алгоритм.

А то ведь можна рехнуться в этих pcat,pcat1,pch,pch1,pcl...я серъёзно :( они ведь еще внутри whileнеоднократно замословатейшим образом изменяются, тут не уследишь...

Удачи.


Страницы:   1 2

Наверх

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