Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Problem mit Array
knittel - Mo 02.08.10 17:34
Titel: Problem mit Array
Hallo allerseits,
ich bin neu hier und habe ein problem bei einem Array, bin noch ein blutiger Anfänger.
Ich entwickle gerade ein Spiel bei dem man seine Einheiten rundenbasiert steuert. Die Einheiten können Minen legen. Sobald ein Gegner in einen Bereich um die Mine mit dem Abstand 24 kommt, soll die Mine explodieren und alle Gegner darin Schaden erhalten.
Danach soll logischerweise die Mine verschwinden und das Array soll entsprechend gekürzt werden.
Ich habe folgenden Code dafür.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure MineActive (); var i, j, a: integer; begin a:=0; for i:= 0 To High(ShapePlayerMines) do begin if (ShapePlayerMines[i].Visible = false) then begin a:=a+1; ShapePlayerMines[i].Free; for j:= i to (High(ShapePlayerMines)-1) do begin ShapePlayerMines[j]:=ShapePlayerMines[j+1]; end; end; end; SetLength(ShapePlayerMines,(Length(ShapePlayerMines)-a)); end; |
Die procedure, in der das Betreten der Mine überprüft wird.
Delphi-Quelltext
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:
| procedure CheckCPUandLifeOfPlayerUnits (); var i, a, Amount: integer; begin
for i:= 0 To High(ShapePlayerMines) do begin for a:= 0 To High(ShapeEnemies) do begin if ((ShapeEnemies[a].Left > ShapePlayerMines[i].Left - 24) AND (ShapeEnemies[a].Left < ShapePlayerMines[i].Left + 26) AND (ShapeEnemies[a].Top > ShapePlayerMines[i].Top - 24) AND (ShapeEnemies[a].Top < ShapePlayerMines[i].Top + 26)) then begin ShapePlayerMines[i].Visible:=false; EnemyBots[a, 2]:=EnemyBots[a, 2] - 1; CheckEnemyAlive (StrToInt(ShapePlayerMines[i].Hint)); end; end; end; MineActive (); end; |
Das Spiel funktioniert sehr lange gut. Irgendwann mal nachdem etwa 12 oder 13 Minen explodiert sind kommt plötzlich folgende Fehlermeldung:
'Access Violation at 00007469'
Danke im voraus. :)
Teekeks - Mo 02.08.10 18:04
Bist du dir denn sicher das du auch diese ganzen Klassen in dem Array Initialisiert hast?
Flamefire - Mo 02.08.10 20:07
das problem ist eher:
du zählst alle minen durch
löschst eine in der mitte und verschiebst alle danach
ABER zählst bis zur letzten durch
-->bei 1 gelöschten ist die letzte=vorletzte und wird 2 mal geprüft.
angenommen du "free"st diese vorletzte und prüfst dann die letzte --> AV
Lösung: äußere schleife eine while schleife mit variablen oberen zähler (nämlich "Length(ShapePlayerMines)-a") und die innere for schleife mit "Length(ShapePlayerMines)-a-1" als obere schranke
Xion - Mo 02.08.10 20:16
knittel hat folgendes geschrieben : |
Das Spiel funktioniert sehr lange gut. Irgendwann mal nachdem etwa 12 oder 13 Minen explodiert sind kommt plötzlich folgende Fehlermeldung:
'Access Violation at 00007469' |
Zum Hintergrund bisschen was:
Access Violation heißt immer du schreibst/liest wo rum wo du nicht darfst. Dafür kriegst du auf die Finger. Dass das erst irgendwann auftritt (und nicht schon beim ersten mal) ist ne ziemlich gemeine Sache. Es kann sogar so sein dass es erst nach ner Woche mal zum Fehler kommt wenn du grad wo anders rumbastelst. Vorher hast du wohl nie einen verbotenen Bereich erwischt und sonst irgendwo rumgelesen, was aber niemanden gestört hat. Das tolle an dem Fehler ist, dass du oft weder von Delphi gesagt bekommst wo der Fehler aufgetreten ist, die Fehlermeldung absolut nichtssagen ist und eben nicht immer erscheint.
Flamefire - Mo 02.08.10 22:51
nicht ganz. mit dem delphi-debugger und der call-history kann man die stelle ganz gut finden bzw. eingrenzen.
jaenicke - Di 03.08.10 00:28
Zudem kann man mittels Mapfile und CPU-Fenster auch mit der Speicherstelle ggf. etwas anfangen. Wenn die sehr klein ist (0 oder 10 z.B.), hat man meistens irgendein nicht initialisiertes Objekt. Denn dann wird der Offset der entsprechenden Speicherstelle zu der des Objekts addiert und das ist ja dann 0.
Es ist zwar aber nicht ganz trivial mit den Informationen etwas anzufangen, aber entweder mit dem genannten Debugger und Call Stack oder auch mit MadExcept, Eurekalog oder JclDebug lässt sich da viel herausfinden.
knittel - Di 03.08.10 10:32
Danke erstmal für alle die etwas geschrieben haben.
Ich habe Flamefire's Lösung benutzt und mittlerweile funktioniert's. Ich habe es auch auf die Gegner übertragen, die ja auch sterben können.
Danke nochmals. :)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!