| Autor |
Beitrag |
Popov
      
Beiträge: 1655
Erhaltene Danke: 13
WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
|
Verfasst: Mo 07.04.03 15:45
Ich sehe keinen - aber vielleicht sieht einer von euch es. Anbei ein wenig Code. Mein eigentliches Programm hab ich bis auf diese Zeilen reduziert und leicht modifiziert. Es werden also keine Grafiken geladen, sondern erstellt. Das hat aber auf den Fehler keinen Einfluß.
Wenn man das Programm startet und gleich danach die Leertaste drückt ( und gedrückt läßt) kommt früher oder später eine Fehlermeldung. Das Programm bricht mit einer EAccessViolation Fehlermeldung ab.
Wie gesagt muß man dazu das Programm starten und die Leertaste gedrückt lassen. Bei mir bricht es in der vierten Zeile mit der Fehlermeldung ab. Es kann aber auch später sein, vor allem dann, wenn man die Taste auch später erst gedrückt hat.
Die einzige Komponente die man für dieses Beispiel braucht ist der Timer:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
| implementation
{$R *.DFM}
const MatrixMaxX = 40; MatrixMaxY = 20;
var Matrix: array[0..MatrixMaxX, 0..MatrixMaxY] of Byte; Bmp: TBitmap; BmpA: TBitmap; ax, ay: Integer;
procedure TForm1.FormCreate(Sender: TObject); begin Timer1.Interval := 20; Bmp := TBitmap.Create; Bmp.Width := MatrixMaxX * 16; Bmp.Height := MatrixMaxY * 16;
BmpA := TBitmap.Create; BmpA.Canvas.Brush.Color := clBlack; BmpA.Width := 16; BmpA.Height := 16; end;
procedure TForm1.FormDestroy(Sender: TObject); begin Bmp.Free; BmpA.Free; end;
procedure TForm1.Timer1Timer(Sender: TObject); begin if ay > MatrixMaxX then Exit; if ax > MatrixMaxX then begin ax := -1; ay := ay + 1; end; ax := ax + 1;
Bmp.Canvas.Draw(ax * 16, ay * 16, BmpA); Canvas.Draw(0, 0, Bmp); end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char); begin if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay + 1] := 0; end; |
_________________ Popov
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Mo 07.04.03 16:11
Also soweit ich das sehe initialisierst du die beiden Variablen ax und ay nicht..!
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
mimi
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Mo 07.04.03 16:26
mal ne frage: wo wird in ax und ay geschrieben ? und was soll da drinen stehen ?
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: Mo 07.04.03 17:15
Hi,
es kann nur an dieser Zeile hier liegen:
Quelltext 1:
| if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay + 1] := 0; |
und da es in dieser Zeile nur an der Matrix hinten liegen kann, würde ich mal tippen das es an dem ay+1 liegt... schreib da mal nur ay hin
Au'revoir,
Aya~
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
mimi
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Mo 07.04.03 17:24
jetzt weiß ich woran es liegt: du schreibst im timer -1 hin nun musst du im onkey ereignis eine abfage machen ob -1 ist.... oder nicht....
und du musst im onkey ereinigs schauen ob ay+1 größer als die höhe ist....
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: Mo 07.04.03 17:28
| mimi hat folgendes geschrieben: | jetzt weiß ich woran es liegt: du schreibst im timer -1 hin nun musst du im onkey ereignis eine abfage machen ob -1 ist.... oder nicht....
und du musst im onkey ereinigs schauen ob ay+1 größer als die höhe ist.... |
Nein, denn direkt nachdem er ax:=-1 macht, erhöht er eswieder um 1, so das es dann 0 ist
Au'revoir,
Aya
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
Popov 
      
Beiträge: 1655
Erhaltene Danke: 13
WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
|
Verfasst: Mo 07.04.03 17:35
@Mozi: ax und ay sind globale Variablen. Siehe also da.
@Mimi: Wo wird in ax und ay geschrieben? Siehe Timerprozedur.
Bitte fragt nicht nach Sinn des Codes. Es ist alles entfernt worden was nicht für die Fehlersuche notwendig ist.
@Aya: Es hat mit +1 nichts zu tun. Auch ohne +1 kommt der Fehler. Allerdings siehts du es richtig. Ohne diese Zeile gibt es keine Fehlermeldung.
@Mimi: Die ganzen Rechnungen haben schon ihren Sinn. Auch so:
Quelltext 1:
| if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay] := 0; |
gibt es eine Fehlermeldung.
_________________ Popov
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: Mo 07.04.03 17:38
Hi,
dann mach mal aus dem > ein >= in dieser Zeile:
Quelltext 1: 2:
| if ay > MatrixMaxX then Exit; if ax > MatrixMaxX then begin |
und vorallem mach da mal ein:
MatrixMax Y hin (oder is das absicht?)
Au'revoir,
Aya~
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
mimi
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Mo 07.04.03 17:41
also ich würde mal an deiner stelle bei on KeyPress ausgeben was in ax und ay steht ich wette da steht irgenwas drin.... was da nicht reinsoll
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
Popov 
      
Beiträge: 1655
Erhaltene Danke: 13
WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
|
Verfasst: Mo 07.04.03 18:20
Ich hab den Fehler.
Den hab ich eigentlich schon nach mimi's -1 Hinweis, hab aber par Minuten gebraucht bis ich es gemerkt habe.
Es ist doch so: Delphi ist eine Multidingsbums Sprache. Das heißt, daß Prozeduren Ereignisorientiert aufgerufen werden. Hier haben wir zwei Prozeduren: einen Timer, der alle X Millisekunden aufgerufen wird. Dann haben wir OnKeyPress, das beim Tastenduck aufgerufen wird. Die Frage ist jetzt ob die Prozeduren warten bis die andere fertig ist, oder die andere Prozedur unterbrechen (bzw. parallel aufgerufen werden). In den zweiten Fall kann es vorkommen, daß ax noch -1, während OnKeyPress aufgerufen wird. In diesem Fall wird ax mit einem -1 angesprochen.
Ich hab den Code jetzt so abgeändert und es funktioniert:
Quelltext 1: 2: 3: 4: 5: 6: 7:
| procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char); begin if (ax < 0) or (ax > MatrixMaxX) then Exit; if (ay < 0) or (ay > MatrixMaxY) then Exit;
if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay] := 0; end; |
Also danke für das Brainstorming.
_________________ Popov
Zuletzt bearbeitet von Popov am Mo 07.04.03 18:33, insgesamt 1-mal bearbeitet
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Mo 07.04.03 18:32
| Popov hat folgendes geschrieben: | | Es ist doch so: Delphi ist eine Multidingsbums Sprache. Das heißt, daß Prozeduren Ereignisorientiert aufgerufen werden. Hier haben wir zwei Prozeduren: einen Timer, der alle X Millisekunden aufgerufen wird. Dann haben wir OnKeyPress, das beim Tastenduck aufgerufen wird. Die Frage ist jetzt ob die Prozeduren warten bis die andere fertig ist, oder die andere Prozedur unterbrechen. In den zweiten Fall kann es vorkommen, daß ax noch -1, während OnKeyPress aufgerufen wird. In diesem Fall wird ax mit einem -1 angesprochen. |
Das dürfte aber eigentlich nicht das Problem sein, da die Windows-Messages nacheinander abgerabeitet werden und dein Prog verwendet schließlich keine Threads und ruft auch nirgendwo Application.ProcessMessages auf oder?
Dass ax und ay globale Variablen sind hab ich schon gesehen, aber initialisiert werden sie in dem obigen Code trotzdem nicht.
Aber nachdem jetzt alles funzt hat sich das ja eh erledigt...
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
mimi
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Mo 07.04.03 18:39
doch!
er hat ein Timer der wird immer wieder aufgerufen und wenn er jetzt eine taste drück kann in ax -1 stehen...
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
Popov 
      
Beiträge: 1655
Erhaltene Danke: 13
WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
|
Verfasst: Mo 07.04.03 18:48
| Motzi hat folgendes geschrieben: | | Dass ax und ay globale Variablen sind hab ich schon gesehen, aber initialisiert werden sie in dem obigen Code trotzdem nicht. |
Jetzt sag mal genau was du mit initialisieren meinst. Oder meinst du hier das zuweisen der ersten Werte? Nunja, wäre ax und ay <> 0, dann hätte ich das auf der Grafik gesehen. ax und ay waren also 0 beim Start.
Zu der Sache mit dem Abarbeiten der Prozeduren. Eigentlich bin ich deiner Meinung, aber warum tritt das Problem jetzt nicht auf?
_________________ Popov
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Mo 07.04.03 19:43
| Popov hat folgendes geschrieben: | Jetzt sag mal genau was du mit initialisieren meinst. Oder meinst du hier das zuweisen der ersten Werte? Nunja, wäre ax und ay <> 0, dann hätte ich das auf der Grafik gesehen. ax und ay waren also 0 beim Start.
Zu der Sache mit dem Abarbeiten der Prozeduren. Eigentlich bin ich deiner Meinung, aber warum tritt das Problem jetzt nicht auf? |
Mit initlialisieren meine ich das Zuweisen der Ausgangswerte. Fehlende Initialisierungen könnten teuflische Fehler verursachen die erst viel später auftreten, weshalb die eigentlich Fehlerursache ziemlich schwer festzustellen ist.
Warum der Code jetzt funktioniert? Ganz einfach, weil du jetzt explizit jeden Fall ausschließt, in dem entweder ax oder ay ein nicht existierendes Array-Feld referenzieren! 
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Zuletzt bearbeitet von Motzi am Mo 07.04.03 19:58, insgesamt 2-mal bearbeitet
|
|
mimi
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Mo 07.04.03 19:48
und du hast da einen fehler beoben bei if ax > ay then exit;
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Mo 07.04.03 19:55
Ok.. ich glaube der Fehler ist eine Kombination aus 3 Stellen.. aus dem Original-Code:
1) im OnTimer
Quelltext 1:
| if ay > MatrixMaxX then Exit; // falscher Vergleich |
2)im OnKeyPress
Quelltext 1:
| if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay + 1] := 0; // das +1 weg |
3) im OnTimer
Quelltext 1: 2:
| if ay > MatrixMaxX then if ax > MatrixMaxX then |
In beiden Fällen muss der Vergleich auf >= lauten. Denn wenn ax = MatrixMaxX ist wird es nicht auf -1 zurückgesetzt, aber trotzdem nochmal um 1 erhöht.
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
Popov 
      
Beiträge: 1655
Erhaltene Danke: 13
WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
|
Verfasst: Mo 07.04.03 21:36
Ok, das Problem ist weg. Deshalb ist die Lösung sekundär. Aber mal par Worte zu den Punkten:
Quelltext 1:
| if ay > MatrixMaxX then Exit; // falscher Vergleich |
Ist zwar ein Fehler, aber hat mit dem eigentlichen Problem nichts zu tun, da der Fehler auftrit bevor ay > MatrixMaxY ist. Der Fehler kommt davon, daß es vorher nur ein MatrixMax gab und keine MatrixMaxX / ...Y. Das hat aber mit dem eigentlichen Problem nichts zu tun.
Quelltext 1:
| if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay + 1] := 0; // das +1 weg |
Das +1 ist schon richtig, da hier die Matrixzeile drunter angesprochen wird. Aber auch ohne das +1 gabs den Fehler.
Quelltext 1:
| if ax > MatrixMaxX then |
Das ist auf jeden Fall ein schlimmer Fehler. Das könnte auch der gesuchte Fehler sein. Werde es noch prüfen.
_________________ Popov
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Mo 07.04.03 21:47
| Popov hat folgendes geschrieben: | Quelltext 1:
| if (Key = ' ') and not (ay > MatrixMaxY) then Matrix[ax, ay + 1] := 0; // das +1 weg |
Das +1 ist schon richtig, da hier die Matrixzeile drunter angesprochen wird. Aber auch ohne das +1 gabs den Fehler. |
Das mag schon sein, nur schließt der Vergleich ay > MatrixMaxY den Fall ay = MatrixMaxY nicht aus wodurch dann mit ay + 1 der Index auserhalb der Matrix liegt! Lösung wäre entweder das +1 zu entfernen oder auch hier den Vergleich auf >= umzuändern..
Aber egal.. nachdem der Fehler ja behoben ist braucht man den Code nicht noch weiter zu zerlegen...
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|