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

Вниз

Рекурсивная процедура не компилится D7...   Найти похожие ветки 

 
KIR ©   (2003-09-25 13:16) [0]

... хотя в D6 все работало ОК. Точнее она (процедура) компилится, но при запуске прложение выдает ошибку "List index out of bounds(0)".
Процедура рекурсивно загоняет данные из, я думаю, хорошо всем знакомой таблицы ID PARENID NAME в TreeView


 
Anatoly Podgoretsky ©   (2003-09-25 13:23) [1]

Ошибка индекса массива, списка и т.д.
Программа написана неверно.


 
KIR ©   (2003-09-25 13:46) [2]

Вот полный код (предполагаю, что омибка в методах Create и Free), но что странно на D6 все шло...
Код:

procedure TMainForm.BuildTree(Tree: TTreeView; Root: TExtendedNode; Tp: Integer);
var
ExtNode: TExtendedNode; //описание TExdendedNode см ниже.
DS: tpFIBDataSet;
S: String;
begin
If Root = nil then
S := "PARENTID is null"
else
S := "PARENTID = "+IntToStr(Root.ID);
DS := tpFIBDataSet.Create(nil);
DS.SQLs.SelectSQL.Add("SELECT");
DS.SQLs.SelectSQL.Add("*");
DS.SQLs.SelectSQL.Add("FROM");
DS.SQLs.SelectSQL.Add("GOODS");
DS.SQLs.SelectSQL.Add("WHERE");
DS.SQLs.SelectSQL.Add(S);
DS.SQLs.SelectSQL.Add("AND");
DS.SQLs.SelectSQL.Add("Del = 0");
DS.SQLs.SelectSQL.Add("ORDER BY");
DS.SQLs.SelectSQL.Add("ID");

DS.Transaction := DM1.DefaultTS;
DS.Open;
DS.First;
While not DS.Eof do
begin
ExtNode := Tree.Items.AddChild(Root,DS["Name"]) as TExtendedNode;

ExtNode.ID := DS["ID"];

ExtNode.ItemName := DS["Name"];
If DS["Last"] =1 then
ExtNode.Cost := DS["Cost"];
ExtNode.Kod := DS["Kod"];
ExtNode.IsBonus := DS["IsBonus"];
If DS["Last"] = 1 then
begin
ExtNode.Text := IntToStr(DS["Kod"])+" - "+FormatFloat("#,##0.",DS["Cost"])+" - "+ExtNode.Text+
" "+IntToStr(DS["KolVo"])+" "+IntToStr(DS["Bron"])+" "+IntToStr(DS["Kredit"]);
ExtNode.Last := True;
ExtNode.KolVo := DS["KolVo"];
ExtNode.Bron := DS["Bron"];
ExtNode.Kredit := DS["Kredit"];
end
else
begin
ExtNode.Last := False;
ExtNode.KolVo := -1;
ExtNode.Bron := -1;
ExtNode.KolVo := -1;
end;
DS.Free;
BuildTree(Tree,ExtNode,Tp);
DS.Next;
end;
DS.Free;
end;

описание TExtendedNode:

TExtendedNode = class(TTreeNode)
private
FID: Integer;
FKod: Variant;
FItemName: String;
FCost: Extended;
FKolVo: Integer;
FBron: Integer;
FKredit: Integer;
FLast: Boolean;
FIsBonus: Byte;
public
property ID: Integer read FID write FID;
property Kod: Variant read FKod write FKod;
property ItemName: String read FItemName write FItemName;
property Cost: Extended read FCost write FCost;
property KolVo: Integer read FKolVo write FKolVo;
property Bron: Integer read FBron write FBron;
property Kredit: Integer read FKredit write FKredit;
property Last: Boolean read FLast write FLast;
property IsBonus: Byte read FIsBonus write FIsBonus;


 
Hooch ©   (2003-09-25 13:56) [3]

в Tools\Debugger options\Language exceptions поставь Stop on Delphi Exceptions и погляди где ошибка вываливается


 
Palladin ©   (2003-09-25 13:56) [4]

DS.Free; что за фигня? как это понимать?


 
Плохиш_   (2003-09-25 14:01) [5]

>KIR © (25.09.03 13:46) [2]

DS.Free;
BuildTree(Tree,ExtNode,Tp);
DS.Next;


Вот это мне больше всего понравилось ;-)


 
Palladin ©   (2003-09-25 14:03) [6]

я именно про это, странно что List index out of bounds...
хотя это наверно есть последствия "жизни после смерти"...


 
KIR ©   (2003-09-25 16:01) [7]

Вообще убрал DS.Free - заработало... но, если я все правильно понимаю, при каждом последующем погружении в рекурсию создается очередной DS, так? И если их не убивать (DS.Free) они (DSы) так и будут висеть в памяти...

А насчет того, что предложил Плохиш_ - ничего не выйдет, потому что построится только одна ветка, а их много (очень)!

P.S. И еще раз: народ, на D6 все работало!?


 
Плохиш_   (2003-09-25 16:13) [8]

>KIR © (25.09.03 16:01) [7]

> А насчет того, что предложил Плохиш_


Интересно, что же предложил Плохиш_? Вообще-то был просто приведён кусок кода из KIR © (25.09.03 13:46) [2]


> Вообще убрал DS.Free - заработало...


Palladin, ты представляешь какой он DS.Free убрал? 8-O


 
Palladin ©   (2003-09-25 16:19) [9]

неа... возможно оба...


> KIR © (25.09.03 16:01) [7]

Ты себе в уме представляешь исполнение этой процедуры?


 
Verg ©   (2003-09-25 16:24) [10]


> И если их не убивать (DS.Free) они (DSы) так и будут висеть
> в памяти...


Да пока цепь рекурсии продолжется они будут, и они ДОЛЖНЫ висеть.

В конце процедуры, т.е. пере выходом есть же ds.free, так что с этим все в порядке.


> P.S. И еще раз: народ, на D6 все работало!?


Случайно. Free освобождает память но ведь не "напрочь" же :))
Так или сяк устроен менеджер кучи у той или иной дельфы - от этого зависит какие будут чудеса твориться при обращении к освобожденной памяти и будут ли эти чудеса заметны "невооруженным глазом" вообще.
Так что, подумайте еще раз о том - что есть рекурсия и что есть динамические объекты в ее контексте.
P.S.
Я бы D7 спасибо сказал, что она хоть и криво, но дала понять где "дыра" в программе.


 
KIR ©   (2003-09-25 18:47) [11]

Было, конечно, так: (2 Плохиш_: Сорри)
//DS.Free;
BuildTree(Tree,ExtNode,Tp);
DS.Next;
DS.Free;

Но все равно глючит, а если так:
//DS.Free;
BuildTree(Tree,ExtNode,Tp);
DS.Next;
//DS.Free;

Все ОК... не пойму, в чем проблема


 
Verg ©   (2003-09-25 18:54) [12]

Давай ка педантично -

.....
> end;
>// DS.Free;
> BuildTree(Tree,ExtNode,Tp);
> DS.Next;
> end; // цикла while
> DS.Free;
> end; // процедуры


Так ?


 
KIR ©   (2003-09-25 19:00) [13]

>Verg совершенно верно, только DS.Free заклментированны и там и там. Т.е. метод DS.Free не вызывается никогда и только тогда все работает...


 
Плохиш_   (2003-09-25 19:05) [14]

>KIR © (25.09.03 19:00) [13]

Так, ладно, будем спрашивать дальше.
На какой строчке происходит ошибка?


 
KIR ©   (2003-09-25 19:08) [15]

>Плохиш_ (25.09.03 19:05) [14]

На вызове процедуры из самой себя


 
Плохиш_   (2003-09-25 19:41) [16]

>KIR

В какой версии говоришь это работало
ExtNode := Tree.Items.AddChild(Root,DS["Name"]) as TExtendedNode;

Ты представляешь, что ты здесь делаешь? 8-O

Ты используешь TTreeNode как TExtendedNode
Так бегом в хелп и читай всё, что относится к TTreeNodes, TTreeNode. Особенно надо обратить внимание на TTreeNode.Data


 
Плохиш_   (2003-09-25 19:47) [17]

так маленький пардон :-)

AddChild создаёт элемент TTreeNode, который не имеет дополнительных полей из TExtendedNode и соответственно не отводит под них память!

Тебе надо создать также нового потомка от TTreeView и переписать в нём AddChild.


 
KIR ©   (2003-09-25 20:00) [18]

>Плохиш_ (25.09.03 19:47) [17]
>Тебе надо создать также нового потомка от TTreeView и переписать в нём AddChild.

А при чем тут DS.Free?
Еще раз: если комментирую DS.Free, все отлично работает, в том числе и AddChild. Информация из дополнительных полей считывается, так что переписывать AddChil, по-моему, нет смысла


 
Плохиш_   (2003-09-26 10:53) [19]

>KIR © (25.09.03 20:00) [18]
> так что переписывать AddChil, по-моему, нет смысла


Хозяин, как говорится, барин :-|

Попробую ещё раз на пальцах: AddChild создал тебе компонент TTreeNode размером, скажем, 50 байт. Ты говоришь фигушки я буду использовать его как TExtendedNode который имеет размер 80 байт.
Как ты думаешь, что происходит, когда ты пишешь в последнии 30 байт? И так много, много раз.

Если ты интересуешься, то это в мире называется "Проблема переполнения буфера"


 
KIR ©   (2003-09-26 12:04) [20]

>Плохиш_ (26.09.03 10:53) [19]

К вопросу об AddChild: если будет желание, загляни в эту ветку завтра или сегодня вечером. Я посмотрю дома поточнее - пример TExtendedNode я взял из Марко Кэнту, кстати, если эта книжка у тебя под рукой, можешь сам полюбопытствовать.


 
Плохиш_   (2003-09-26 14:28) [21]

>KIR © (26.09.03 12:04) [20]

Я не знаю, что ты делаешь в программе, но я думаю, что самый лёгкий и надёжный способ, это сделать TExtendedNode обычным классом и сохранять указатель на него в TTreeNode.Data.



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

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

Наверх




Память: 0.52 MB
Время: 0.02 c
14-27689
Толя
2003-09-22 01:54
2003.10.09
Pchar to Char


1-27439
JOY
2003-09-28 06:04
2003.10.09
1Кто-нибудь пробовал выравнивать по ширине?


3-27382
Smashich
2003-09-18 20:10
2003.10.09
EVENT & MS SQL


4-27766
OHP
2003-08-04 00:25
2003.10.09
RegisterWindowMessage


3-27307
Vick
2003-09-17 16:40
2003.10.09
Функция определения кол-ва дней в месяце