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

Вниз

Free дерева   Найти похожие ветки 

 
KADAN ©   (2004-07-22 16:37) [0]

мне нужно очистить память, выделенную под дерево. думал, что просто будет сделать так:
procedure FreeTree(var T: PTree);
begin
 case T^.NodeType of
   ntType1:
     begin
       FreeTree(T^.Left);
       FreeTree(T^.Right);
     end;
   ntType2:
     FreeTree(T^.Center);
 end;
 dispose(T);
end;

оказалось, так делать нельзя... как проверить, выделена ли память под ветви, а то поятоянно выскакивают AV и IPO.
само дерево выглядит так:

type  
 PTree = ^TTree;
 TTree = record
   case NodeType:TNodeType of
   ntType1:
     (Left, Right: PTree);
   ntType2:
     (Center: PTree);
   ntType3:
     ();
 end;


вообще, это дерево у меня - результат выполнения рекурсивной функции... мне бы хотелось, чтобы при возникновении ошибки эта функция сама бы очистила уже выделенную память и вернула nil.


 
Sandman25 ©   (2004-07-22 16:39) [1]

if T=nil then...


 
KADAN ©   (2004-07-22 16:46) [2]


> if T=nil then...

они не nil в том то и дело....


 
Iconka ©   (2004-07-22 16:47) [3]


>
> > if T=nil then...
>
> они не nil в том то и дело....

тогда

T:= nil
if T=nil then...


 
Sandman25 ©   (2004-07-22 16:49) [4]

[2] KADAN ©   (22.07.04 16:46)

А подумать?
Наводящий вопрос - есть ли какие-нибудь nil в Вашей структуре.


 
KADAN ©   (2004-07-22 16:49) [5]

Iconka ©   (22.07.04 16:47) [3]

простите, недопонял...


 
KADAN ©   (2004-07-22 16:51) [6]

>Sandman25 ©   (22.07.04 16:49) [4]
после вызова метода New Left, Right и Center не nil.


 
Iconka ©   (2004-07-22 16:52) [7]


> простите, недопонял...


шутка :)


 
Sandman25 ©   (2004-07-22 16:52) [8]

[6] KADAN ©   (22.07.04 16:51)

И куда же они указывают, если все дерево состоит всего из одного узла?


 
KADAN ©   (2004-07-22 16:56) [9]


> Sandman25 ©   (22.07.04 16:52) [8]

например, я создаю узел, задаю ему тип ntType1,
создаю левую ветку,
а правую не смог создать (она теперь указывет в никуда).
теперь требуется очистить это все, плюс ко всему очистить все до самого корня.


 
Sandman25 ©   (2004-07-22 16:59) [10]

>а правую не смог создать (она теперь указывет в никуда).

и после этого вызваете
FreeTree(T^.Right)


 
KADAN ©   (2004-07-22 17:01) [11]

T^.Right никуда не указывает, как же я ее буду освобождать?


 
Sandman25 ©   (2004-07-22 17:03) [12]

Вот и я о том же. Вы вызываете FreeTree(T^.Right) и при этом происходит вызов FreeTree с новым параметром T, равным nil. Вопрос - "Нужно ли освобождать память, если T=nil?"


 
KADAN ©   (2004-07-22 17:05) [13]


> Вот и я о том же. Вы вызываете FreeTree(T^.Right) и при
> этом происходит вызов FreeTree с новым параметром T, равным
> nil. Вопрос - "Нужно ли освобождать память, если T=nil?"

я бы с радосьбю так сделал... тока вот nil"ов нету там...


 
Sandman25 ©   (2004-07-22 17:08) [14]

>(она теперь указывет в никуда)

Что Вы под этим понимаете?


 
KADAN ©   (2004-07-22 17:13) [15]

наверное, плохо объяснил систему...

function GetTree(параметры):PTree;
begin
try
 new(result); //после этого right и left не nil... и бог знает куда они указывают
 result^.NodeType:=ntType1;
 result^.left:=GetTree(новыепараметры1);
 result^.right:=GetTree(новыепараметры2);
except
 FreeTree(result);
end;
end;


допустим, при создании левой ветки выпал еррор, идем в FreeTree, правая ветка при этом указывает в никуда (но не в nil... например, в 0000001C), очистить мы ее не можем, и определить, что под не ничего не выделено тоже.


 
Sandman25 ©   (2004-07-22 17:16) [16]

new(result);
ZeroMemory(result^, SizeOf(TTree));
...
и теперь неиспользуемые поля будут nil


 
Sandman25 ©   (2004-07-22 17:18) [17]

или лучше
ZeroMemory(Result^, SizeOf(Result^));


 
KADAN ©   (2004-07-22 17:19) [18]

ZeroMemory... отлично! наверное это мне и надо было...


 
ИдиотЪ   (2004-07-22 17:19) [19]

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


 
VMcL ©   (2004-07-22 17:20) [20]

>>Sandman25 ©  (22.07.04 17:18) [17]

+ лучше FillChar, а не ZeroMemory.


 
Sandman25 ©   (2004-07-22 17:20) [21]

И еще книжку почитать, про инициализацию динамических структур :)


 
Sandman25 ©   (2004-07-22 17:23) [22]

[20] VMcL ©   (22.07.04 17:20)

C точки зрения скорости - да.
С точки зрения читабельности/структурности - нет.

Если процедура вызывается с одними и теми же параметрами, то следует завести новую процедуру с уменьшенным количеством параметров. Рефакторингом называется :)


 
VMcL ©   (2004-07-22 17:32) [23]

>>Sandman25 ©  (22.07.04 17:23) [22]

ИМХО, рефакторинг не должен ухудшать быстродействие. И с каких это пор FillChar нечитабельной стала? Ну да ладно. Это не принципиальный вопрос.


 
Sandman25 ©   (2004-07-22 17:35) [24]

>ИМХО, рефакторинг не должен ухудшать быстродействие

Рефакторингу глубоко наплевать на быстродейтвие. Все "отцы-основатели" прямо об этом пишут в самом начале своих лекциях.


 
VMcL ©   (2004-07-22 21:40) [25]

>>Sandman25 ©  (22.07.04 17:35) [24]

Значит, я плохой сын :)



Страницы: 1 вся ветка

Текущий архив: 2004.08.08;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.038 c
14-1090736827
SergP
2004-07-25 10:27
2004.08.08
PHP. Нужно что-то наподобии дельфийского IntToHex


1-1090749689
Endi
2004-07-25 14:01
2004.08.08
Ошибка доступа при згрузке файла в реестр


6-1086263450
MasterA
2004-06-03 15:50
2004.08.08
Компонент


14-1090438685
k@rt
2004-07-21 23:38
2004.08.08
Winamp + 5 колонок


1-1090314166
rustamus
2004-07-20 13:02
2004.08.08
DhtmlEdit