Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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.5 MB
Время: 0.036 c
8-1091519717
parovoZZ
2004-08-03 11:55
2004.11.21
Флипинг и блитинг


1-1099910092
slaga
2004-11-08 13:34
2004.11.21
Замена Glyph на батоне


14-1099135392
Yuri Btr
2004-10-30 15:23
2004.11.21
Входящие подключения - проблема с модемом в XP


14-1099419072
Роман
2004-11-02 21:11
2004.11.21
Есть авторы крутых прог?


1-1099817308
Wood
2004-11-07 11:48
2004.11.21
Обращение к TMenuItem





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский