Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.10.09;
Скачать: [xml.tar.bz2];

Вниз

Рекурсивная процедура не компилится 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.01 c
3-27344
3APA3A
2003-09-19 23:56
2003.10.09
Можно ли создать такую таблицу?


1-27563
Kremen
2003-09-29 15:30
2003.10.09
Разрешение экрана


3-27414
NAlexey
2003-09-18 08:53
2003.10.09
Interbase 5.0 - missing registry


3-27312
leonon
2003-09-15 17:35
2003.10.09
временные db файлы при формировании запросов


1-27598
diww
2003-09-30 12:54
2003.10.09
Как удалить из файла N символов начиная с I?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский