Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Процедура вызывает AV [D7, XP]


Страницы:   1 2 3 4 5

pavel_guzhanov ©   (2010-04-18 19:36:00) 

Вот такой вот код процедуры:

procedure TMainForm.OnClickImage(sender:TObject);
var Name:String[10];
   i, j, k, l,m,c, a, x, y, xa, ya:SmallInt;
   BitMap, BitMapR : Graphics.TBitMap;
   P, PR : PByteArray;
   Image1, Image2: TImage;
   SL:TStringList;        
   S:String;
begin
 SL:=TStringList.Create;
 Name:=TControl(Sender as TImage).Name;
 y:=StrToInt(copy(name, 2, 2));
 x:=StrToInt(copy(name, 4, 2));
 m:=0;
 c:=0;
 try
   if Pan[y, x]<>nil then
     SL.Add(String(Pan[y, x].Name))
   else
     SL.Add('');
   while m<=c do
   begin
     y:=StrToInt(copy(name, 2, 2));
     x:=StrToInt(copy(name, 4, 2));
     for k:=1 to 4 do
     begin
       case k of
       1:begin
           xa:=x+1;
           ya:=y;
         end;
       2:begin
           xa:=x;
           ya:=y+1;
         end;
       3:begin
           xa:=x-1;
           ya:=y;
         end;
       4:begin
           xa:=x;
           ya:=y-1;
         end;
       end; //case
       if (xa<1) or (ya<1) or (xa>18) or (ya>12) or (Pan[yA,xA]=nil) then
         continue;
       Image1:=Pan[y, x];
       Image2:=Pan[ya, xa];
       BitMap:=Image1.Picture.Bitmap;
       BitMapR:=Image2.Picture.Bitmap;
       for i:=0 to Bitmap.Height - 1 do
       begin
         P := Bitmap.ScanLine[i];
         PR:=BitMapR.ScanLine[i];
         if not CompareMem(p, pr, BitMap.Width) then
         begin
           j:=i;
           Break;
         end;//if not
         j:=i;
       end;//for i
       if j=Bitmap.Height - 1 then  
       begin
         a:=0;

         for l:=0 to SL.Count-1 do
         begin
           if String(Pan[ya, xa].Name)=SL.Strings[l] then
           begin
             a:=l;
             break;
           end; //if string
           a:=l;
         end;// for l

       if a=SL.Count-1 then  
         SL.Add(String(Pan[ya, xa].Name));
       c:=SL.Count;
       end; //if j
       if (SL.Count>1) and (m<c) then
       begin
         name:=SL.Strings[m];
       end;// if sl.count and
       S:='';
       for l:=0 to SL.Count-1 do
       begin
         S:=S+SL.Strings[l];
       end; //for l
     end; //for k
     inc(m);
   end; //while
   for l:=0 to SL.Count-1 do
   begin
     if sl.Count>1 then
     begin
       y:=StrToInt(copy(SL.Strings[l], 2, 2));
       x:=StrToInt(copy(SL.Strings[l], 4, 2));
       pan[y,x].Free;
       pan[y,x]:=nil;
     end;// if sl.count
   end; //for l
   for i := 0 to 11 do
   begin
     for j:=0 to 17 do
     begin
       if pan[i+1, j+1]<>nil then
         pan[i+1,j+1].Parent:=Panel1;
     end; //for j
   end; //for i
 finally
   SL.Destroy;
 end;
end;


Все отрабатывает правильно. Но... При пошаговой отладке, после секции finally по клавише F7 попадаю на end; который закрывает процедуру. А после него вылетает AV. Подскажите пожалуйста, откуда AV и как с ним бороться?


pavel_guzhanov   (2010-04-26 20:17:00) [61]

А можно ли перед удалением компонента из массива также сделать, чтобы за компонентом не осталось никаких процедур? Если можно, то как?
Пробую сделать так:
       TImage(pan[y,x]).OnClick:=nil;
       pan[y,x].Free;
       pan[y,x]:=nil;

но на первой строке опять получаю AV


jack128_   (2010-04-25 23:52:00) [62]

Павел, ты б к Юрий ©  [11] прислушал бы.


Дмитрий Белькевич   (2010-04-25 00:24:00) [63]


>  После завершающего end'а сразу вылетает AV.


Если валится на end'ах, обычно это признак порушенного стёка. Например, неверным вызовом сторонних функций из длл.


Anatoly Podgoretsky   (2010-04-24 18:47:00) [64]

> pavel_guzhanov  (24.04.2010 17:06:28)  [28]

Ну и зачем тогда туда лезешь?


sniknik   (2010-04-24 17:23:00) [65]

> Подозрительны пара мест.
нашел еще ...
procedure TMainForm. OnClickImage(sender:TObject);
странное название... похоже получено не "стандартно" кликом на имидж, "обозвано" специально... зачем? возможно делана одна отдельная процедура, чтобы присваивать обработчикам многих динамически созданных иммеджей (массиву, которым рулит эта самая процедура (???)).
если так, и если это те самые которые после внутри процедуры удаляются...  то стоит ли удивляться AV?


pavel_guzhanov   (2010-04-24 17:10:00) [66]

это процедура
procedure       GetDynaMethod;
{       function        GetDynaMethod(vmt: TClass; selector: Smallint) : Pointer;       }
asm
       { ->    EAX     vmt of class            }
       {       SI      dynamic method index    }
       { <-    ESI pointer to routine  }
       {       ZF = 0 if found         }
       {       trashes: EAX, ECX               }

       PUSH    EDI
       XCHG    EAX,ESI
       JMP     @@haveVMT
@@outerLoop:
       MOV     ESI,[ESI]
@@haveVMT:
       MOV     EDI,[ESI].vmtDynamicTable
       TEST    EDI,EDI
       JE      @parent
       MOVZX   ECX,word ptr [EDI]
       PUSH    ECX
       ADD     EDI,2
       REPNE   SCASW
       JE      @@found
       POP     ECX
@parent:
       MOV     ESI,[ESI].vmtParent
       TEST    ESI,ESI
       JNE     @@outerLoop
       JMP     @@exit

@@found:
       POP     EAX
       ADD     EAX,EAX
       SUB     EAX,ECX         { this will always clear the Z-flag ! }
       MOV     ESI,[EDI+EAX*2-4]

@@exit:
       POP     EDI
end;


pavel_guzhanov   (2010-04-24 17:06:00) [67]

Включил дебаг DCU. Падает вот в этом куске файла System на выделенной строке:

@@haveVMT:
      MOV     EDI,[ESI].vmtDynamicTable
       TEST    EDI,EDI
       JE      @parent
       MOVZX   ECX,word ptr [EDI]
       PUSH    ECX
       ADD     EDI,2
       REPNE   SCASW
       JE      @@found
       POP     ECX


Что сие обозначает, я не знаю :о(


jack128_   (2010-04-20 10:30:00) [68]


> что то я в хелпе от 2007ой дельфи не могу найти эту фразу.
>  Значит в этой версии - можно Destroy юзать??

а, нашел. Тогда ладно.


jack128_   (2010-04-20 10:29:00) [69]


> F1: Do not call Destroy directly. Use the Free method.

что то я в хелпе от 2007ой дельфи не могу найти эту фразу. Значит в этой версии - можно Destroy юзать??


Германн   (2010-04-20 00:58:00) [70]


> Какой такой стек, когда есть прекрасный сервис по удаленной
> отладке программ http://delphimaster.ru/cgi-bin/forum.pl

Уж очень тормозной этот сервис!


DVM   (2010-04-20 00:43:00) [71]


> Игорь Шевченко ©   (18.04.10 21:53) [15]
> Delphi в момент исключения показывает стек вызовов, если
> кнопку Break нажать...

Какой такой стек, когда есть прекрасный сервис по удаленной отладке программ http://delphimaster.ru/cgi-bin/forum.pl


Loginov Dmitry   (2010-04-20 00:28:00) [72]


> а чем Destroy не устраивает?


F1: Do not call Destroy directly. Use the Free method.


_Юрий   (2010-04-19 21:19:00) [73]

Стек вызовов посмотреть было бы не лишним.
Что еще можно сделать - собрать с включенной галкой "Use Debug DCU's"
Вероятно, информации о случившемся будет больше


pavel_guzhanov   (2010-04-19 20:17:00) [74]

убрал try - finally - end. Все равно после SL.Destroy (на этой строке ставлю брекпоинт) по F7 перехожу на end, а после него AV.

Изменение SL.Destroy на SL.Free ничего не изменило.


_Юрий   (2010-04-19 19:10:00) [75]


> а чем Destroy не устраивает?  Или FreeAndNil ?


FreeAndNil для данного случая вызывает две лишниеоперации (присвоение nil переменной, которая больше не используется, проверка на nil переменной, которая не может быть nil'ом в данном случае в принципе),
а Free - всего одну лишнюю операцию (проверка на nil того, что nil'ом быть не может)
Так что Free тут лучше, чем FreeAndNil


jack128_   (2010-04-19 16:18:00) [76]


> Чем Free не устраивает?

а чем Destroy не устраивает?  Или FreeAndNil ?


Anatoly Podgoretsky   (2010-04-19 00:26:00) [77]

> Loginov Dmitry  (19.04.2010 00:22:17)  [17]

Тем что работает без ошибок, а у Destroy есть такая возможность.


Loginov Dmitry   (2010-04-19 00:22:00) [78]


> При пошаговой отладке, после секции finally по клавише F7
> попадаю на end; который закрывает процедуру. А после него
> вылетает AV. Подскажите пожалуйста, откуда AV и как с ним
> бороться?
>


Правильно делает, что попадает в  finally, а ошибку выдает уже в самом конце.

В данном примере нужно просто выяснить на какой именно строке происходит AV.
Можно каждую строчку завернуть в TRY..EXCEPT и логгировать ошибки. Где-то должна вылезти.


> Подозрительны пара мест.
>
> P := Bitmap.ScanLine[i];          
> PR:=BitMapR.ScanLine[i];


Хорошо, если Height у обоих одинаковый.

У меня больше подозрение вызывает такое место:
if not CompareMem(P, PR, BitMap.Width) then

(но если пиксели действительно кодируются 1-м байтом, то шут с ними)


>   finally
>     SL.Destroy;
>   end;


Чем Freeне устраивает?


Демо   (2010-04-18 21:55:00) [79]

Подозрительны пара мест.

P := Bitmap.ScanLine[i];          
PR:=BitMapR.ScanLine[i];


Здесь нет утечки памяти?

и

pan[y,x].Free;
pan[y,x]:=nil;


А pan[y,x] больше нигде не используется?
Нет ли назначенной процедуры-обработчика на эти pan[x,y] ?


Игорь Шевченко   (2010-04-18 21:53:00) [80]

Delphi в момент исключения показывает стек вызовов, если кнопку Break нажать...


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо