Форум: "Потрепаться";
Текущий архив: 2004.11.21;
Скачать: [xml.tar.bz2];
ВнизГлюки Делфи 6 Найти похожие ветки
← →
DelphiN! © (2004-10-30 14:01) [0]Сегодня обнаружил глюк компилятора Делфи 6:
procedure Button1Click(Sender: TObject);
var
strl: TStringList;
i: Integer;
Item: TListItem;
Ico:TIcon;
A: array [0..78] of Char;
dd:integer;
begin
if DirectoryDialog1.Execute then
begin
//Допустим Edit1.text теперь = C:\1
Edit1.Text := SelectDirectoryDialog1.Directory;
strl := TStringList.Create;
//В strl теперь список файлов каталога C:\1
strl := Main.FindUnderFiles(Edit1.Text,"*.exe");
//Очищаю ImageList
Icons.Clear;
//В dd теперь кол-во элементов strl-а, допустим 37-1=36
dd:=(strl.Count-1);
for i := 0 to dd do //Цикл от 0-я до 36-ти
begin
//Добавляю в ListView строку
Item := ListView1.Items.Add;
//Заполняю созданую в ListView строку
//Ошибка вылетает тут: ListIndex out of Bounds(37)
//при !!!37-ом(должно быть только 36)!!! обороте цикла
Item.Caption := strl.Strings[i];
//Копирую строку в А
StrPCopy(A, strl.Strings[i]);
//Добавляю в Image1.Picture.Icon иконку файла
//Путь к которому содержиться в A
Image1.Picture.Icon.Handle := ExtractIcon(HInstance, A, 0);
//Добавляю иконку из Image1 в ImageList
Icons.AddIcon(Image1.Picture.Icon);
//Присваиваю полю ListView-a номер иконки
Item.ImageIndex := i;
//без этой сроки Создается исключение:
//List index out of Bounds (37)
IF I=DD THEN BREAK;
end
end
end;
Чем может быть вызвано данное исключение? Код на мой взгляд абсолютно правильный, и до 37-го элемента цикл дойти никак не может, но тем немение это происходит, почему? Это глюк Делфи, или я уже совсем переработал?
← →
Palladin © (2004-10-31 04:07) [1]Это твой глюк естественно...
объясни...
на кой черт тебе нужно было писать
StrPCopy(A, strl.Strings[i]);
когда можно написать
a:=copy(strl[i],1,79)
?
если не видишь разницы между array [0..78] of char (кстати на кой черт этот массив нужен?) и PChar то не стоит пользоватся функциями работаюзщими со строками и принимающими PChar...
← →
DiamondShark © (2004-10-31 11:13) [2]
> StrPCopy(A, strl.Strings[i]);
А если строка длиннее 78 символов?
← →
Юрий Зотов © (2004-10-31 11:20) [3]> ... обнаружил глюк компилятора
Если водитель врезался в столб, то виноват столб?
← →
DiamondShark © (2004-10-31 11:22) [4]
> Если водитель врезался в столб, то виноват столб?
Нет. Автомобиль.
← →
Anatoly Podgoretsky © (2004-10-31 12:01) [5]Кто угодно, только не водитель.
В процедуре надо не ошибки убирать, а всю процедуру с нуля переписать.
← →
Cobalt © (2004-10-31 12:36) [6]Попробуй использовать отладку - и посмотреть, какие переменные имеют какие значения - там и увидишь, что к чему.
← →
VID © (2004-10-31 12:57) [7]Приведённый тобою код, каким кривым он бы не являлся, никак не должен давать 37-ой итерации в цикле... что что-то темнишь...
← →
VID © (2004-10-31 12:59) [8]т.е. 38 итерации
← →
VID © (2004-10-31 13:06) [9]и ещё, как бы там ни было, но заранее (пока ты ещё возможно не стал "великим мегапрограммером") хочу обратить твоё внимание на то, что объекты типа TStringList после создания и использования надо и уничтожать. Если ты думаешь что lst:TStringList, объявлен в теле процедуры и будет уничтожен автоматически при выходе из процедуры - ты ошибаешься. У тебя будет утечка памяти. Удалять такие объекты лучше всего так
Lst := TStringList.Create;
try
// здесь выполняем весь код, которому требуется этот lst
finally
Lst.free;
end;
Также обрати внимание на то что к элементам списка TStringList можно обращаться не только через метод Strings (lst.strings[i]) но и напрямую -lst[i]
.
Переменная dd (dd:=(strl.Count-1)) вообще не нужна. Правильней будет такая запись:For I:=0 to strl.count-1 do....
И ещё... Ближайшие четыре-пять лет не говори, что нашёл у комплятора дельфи глюк ;) Рано тебе ещё :)
← →
Palladin © (2004-11-01 06:01) [10]
> [7] VID © (31.10.04 12:57)
ошибаешься
← →
DelphiN! © (2004-11-01 07:20) [11]>Palladin © (31.10.04 04:07) [1]
Ну а почему появляется лишняя интерация я так и не понял,
и какая разница между
StrPCopy(A, strl.Strings[i]);
и
a:=copy(strl[i],1,79)
Когда прогоняю под отладчиком, он сразу пишет что strl.count-1 = strl.count, тоесть -1 он не учитывает ...
← →
KSergey © (2004-11-01 09:41) [12]> [11] DelphiN! © (01.11.04 07:20)
> StrPCopy(A, strl.Strings[i]);
> и
> a:=copy(strl[i],1,79)
В первом случае копируется до первого встретившегося в памяти символа с кодом 0, во втором - ровно 79 байт, не больше и не меньше.
> Когда прогоняю под отладчиком, он сразу пишет что
> strl.count-1 = strl.count
Чего??? Это как так???
← →
DelphiN! © (2004-11-02 07:50) [13]Вобщем так:
присваиваю переменной dd значение strl.count-1(dd := strl.count-1), теперь если strl.count = 37, то dd = 36(все правильно).
Далее делаем цикл (for i := 0 to dd do ... ) Цикл будет выполнять и 37-ю итерацию, хотя dd = 36! Данный глюк возникает только в вышеприведенном мной коде. Если заменить строку for i := 0 to dd do на for i := 0 to strl.count-1 do ничего не изменится.
Как только программа входит в цикл содержимое dd под отладчиком не показывается(подсказка не появляется), но на 36-й итерации условие "IF I=DD THEN BREAK;" выполняется, из этого следует что dd = 36, однако если убрать строчку IF I=DD THEN BREAK;, то цикл выполняет 37-ю итерацию, при том что dd=36!!! Почему??
← →
sniknik © (2004-11-02 08:35) [14]может не понимаю чего, но
for i := 0 to 36 do ...
ровно 37 итеаций, и это правильно!
для 36-и (если вдруг это надо) будет
for i := 1 to 36 do ...
непонимаю где ошибка, в чем?
← →
DelphiN! © (2004-11-02 10:34) [15]sniknik © (02.11.04 08:35) [14]
Я считаю с 0-я. Появляется лишняя итерация. Если сделать примерно такую структуру то все будет работать:
for i := 0 to 36 do
//В нормальном цикле BREAK никогда не выполнится, но в
//приведенном мной выше коде выполняется
if i = 37 then BREAK;
← →
sniknik © (2004-11-02 11:23) [16]ключевое слово в нормальном. ;о)))
у тебя вот это обьявление
...
A: array [0..78] of Char;
dd:integer;
...
росполагает переменную dd сразу после масива A
а
StrPCopy(A, strl.Strings[i]);
ExtractIcon(HInstance, A, 0);
работают с масивом как областью память (без учета переполнения) и вероятно просто перетирают значение dd который лежит прамо за массивом.
сделай массив побольше (проверь), намного больше например A: array [0..1078] of Char;
и/или перенеси обьявление dd перед массивом.
ситуация должна измениться.
(это просто для понимания ситуации, а лучше прислушатся к советам даваемым ранее)
← →
Palladin © (2004-11-02 17:56) [17]не вероятно перетирают, а точно перетирают...
> [15] DelphiN! © (02.11.04 10:34)
обратил бы внимание на указание что PChar это совсем не array [0..78] of char давно бы уже во всем разобрался... но нет... не слушаешь что тебе говорят...
← →
DelphiN! © (2004-11-03 06:25) [18]Ясно, всем большое спасибо!
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.11.21;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.042 c