AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Zugriffsverletzung nach Modulus

Ein Thema von RebellX · begonnen am 20. Apr 2010 · letzter Beitrag vom 22. Apr 2010
Antwort Antwort
Seite 1 von 2  1 2      
RebellX

Registriert seit: 21. Feb 2009
8 Beiträge
 
Delphi 7 Enterprise
 
#1

Zugriffsverletzung nach Modulus

  Alt 20. Apr 2010, 23:00
Hi,

sitze schon seit einer Weile an folgendem Problem:

In einem Spiel soll ein Spieler durch Karten bewegt werden. Dazu habe ich eine Funktion zur Auswertung der Karten geschrieben. Doch nach einer Konstanten Zahl an Testläufen kommt es immer zu folgendem Problem:

Zitat:
... Problem mit folgender Meldung auf: 'Zugriffsverletzung bei 0x0040c5ad: Schreiben von Adresse 0x00030fc0'. Prozess angehalten...
Die Meldung erscheint zusammen mit dem CPU-Fenster, dort wird immer eins von beiden angezeigt:

Zitat:
push ebx
push $00000400
Danach war eine weitere Ausführung des Programms nicht mehr möglich...

Ich hab soweit Code auskommentiert und konnte herausfinden, das ohne folgende Zeilen das Problem nicht mehr auftritt:

player.angle := (player.angle - 1 + 4) mod 4; player.angle := (player.angle + 1 + 4) mod 4; player.angle := (player.angle + 2 + 4) mod 4; player.angle sollte immer in dem Bereich zwischen 0 und 3 gehalten werden und wird auch nur so geändert. Außerdem sollte das keine Zugriffsverletzung auslösen...

Weiß jemand, woher soetwas stammen könnte?

Schonmal Danke im Vorraus

RebellX


P.S.: Ich benutze statische und dynamische Arrays, doch auch wenn ich auf die nicht mehr zugreife tritt das Problem auf.

P.P.S.: Ich benutze Delphi 7
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#2

Re: Zugriffsverletzung nach Modulus

  Alt 20. Apr 2010, 23:14
Mal ne doofe Idee: kann es sein das du Player irgendwo freigegeben hast (ist das ein Objekt oder ein Record?)

Ich glaube um ein bisschen mehr Code-Preisgabe wirst du hierbei nicht herumkommen.
  Mit Zitat antworten Zitat
RebellX

Registriert seit: 21. Feb 2009
8 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Zugriffsverletzung nach Modulus

  Alt 20. Apr 2010, 23:47
Zitat:
Mal ne doofe Idee: kann es sein das du Player irgendwo freigegeben hast (ist das ein Objekt oder ein Record?) Was sagt die Glaskugel?
Kann eigentlich nicht sein, da
A: player ist in der procedure mit var übergeben worden, sonst aber ein array [1..8] of tplayer (record)
B: Ich davor und danach darauf zugreifen kann, wenn ich die o.g. Zeilen auskommentiere
C: Ich recht wenig freigebe, da das meiste statisch ist und ich mich so nicht drum kümmern muss

Das ganze Projekt ist eine Art Brettspiel. Bis zu 8 Spieler können durch 5 Aktionen pro Zug über ein Spielfeld sich bewegen und müssen Punkte erreichen. Dabei werden sie zusätzlich von den verschiedenen Feldern des Spielfeldes bewegt.
Heißt also in der Berechnung hat jeder Spieler eine X und Y Koordinate sowie eine Orientierung (halt die Eigenschaft angle, also 0, 90, 180, 270° als 0-3 dargestellt).
Zur Anzeige der Bewegung wird dafür wieder rückwärts eine "Animation" erstellt, sprich es wird gespeichert, wie der Spieler bewegt wurde und er wird fürs Anzeigen zurückbewegt. Diese "Animation" wird dann immer weiter verringert, bis der Spieler da angezeigt wird, wo er tatsächlich steht. Das funktionioniert auch ohne die drei Zeilen ohne Probs. Nur sind die unumgänglich um die Spieler zu drehen (oder wie könnte man das einfacher machen?)

Ein paar Definitionen von TPlayer etc. :

Delphi-Quellcode:
type
  TPlayer = record
    X, Y, angle: byte;
    //Animation
    ani_x, ani_y, ani_z, ani_angle, ani_wait: array of smallint;
    ani_count: byte;
    //... unwichtige booleanwerte für Handkarten etc, noch nicht implementiert...
  end;

const
  Move_1 = $01;
  Move_2 = $02;
  Move_3 = $03;
  Turn_Left = $04;
  Turn_Right = $05;
  U_Turn = $06;
  Back_Up = $07;
Die Methode mit der Berechnung:

Delphi-Quellcode:
procedure execute(befehl: byte; var Aplayer: tplayer);
var i: byte;
begin
  if (befehl = 0) or (befehl > 7) then exit;
  if befehl <= move_3 then
    for i := 1 to befehl do
    begin
      moveplayer(aplayer, aplayer.angle);
    end
  else
  if befehl = Turn_left then
  begin
    aplayer.angle := (aplayer.angle - 1 + 4) mod 4;
    addanimate(aplayer, AT_Angle, +30);
  end
  else
  if befehl = Turn_Right then
  begin
    aplayer.angle := (aplayer.angle + 1 + 4) mod 4;
    addanimate(aplayer, AT_Angle, -30);
  end
  else
  if befehl = U_Turn then
  begin
    aplayer.angle := (aplayer.angle + 2 + 4) mod 4;
    if random(2) = 1 then addanimate(aplayer, AT_Angle, -60)
    else
    addanimate(aplayer, AT_Angle, +60);
  end
  else
  if befehl = Back_Up then
  begin
    moveplayer(aplayer, (aplayer.angle + 2 + 4) mod 4);
  end;
end;
Moveplayer und addanimate arbeiten ohne Probleme und auch das Auskommentiere schafft keine Besserung.

P.S.: Player heißt da Aplayer, da Player im Hauptprogramm eben ein Array ist
  Mit Zitat antworten Zitat
Benutzerbild von Billa
Billa

Registriert seit: 11. Aug 2003
237 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Zugriffsverletzung nach Modulus

  Alt 21. Apr 2010, 07:51
Benutze einfach mal eine Hilfsvariable und teile

player.angle := (player.angle - 1 + 4) mod 4; in mehrere Anweisungen auf. Auf die Art sieht man z.B. Bereichsunter- oder überschreitungen (etwa durch die Reihenfolge, in der die Summierung ausgewertet wird) viel eher. Player.Angle ist ja BYTE ... also besser erst +4 und dann -1.... nur so eine (ungetestete) Idee ...
Gruß Billa

Nur weil ich paranoid bin, heißt das nicht, daß die da draussen nicht hinter mir her sind....
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#5

Re: Zugriffsverletzung nach Modulus

  Alt 21. Apr 2010, 07:58
Der Teil aus dem CPU-Fenster passt absolut nicht mit deiner Code-Zeile zusammen.

Kannst du mal in den Optionen die Bereichüberprüfung anschalten.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
RebellX

Registriert seit: 21. Feb 2009
8 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Zugriffsverletzung nach Modulus

  Alt 21. Apr 2010, 08:29
Bereichsprüfung ist eigentlich schon angeschaltet gewesen, sofern ich mich nicht irre.

zumindest habe ich in jeder Unit {+R} gesetzt gehabt, wobei player.angle nur in case Structuren verglichen wird...

Ob es -1+4 ist oder +1+4 macht keinen Unterschied, auch wenn ich -1+4 rausnehme tritt der Fehler auf.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#7

Re: Zugriffsverletzung nach Modulus

  Alt 21. Apr 2010, 08:57
Eine Rechenoperation kann keine Zugriffsverletzung auslösen, also ist es egal ob +1, -1 oder sonstwas.

Es kann höchstens eine Zugriffsverletzung beim Zugriff auf Player erfolgen.
Code:
player.angle := player.angle;
       ^               ^
       ^               Zugriffverletzung "Lesen von Adresse"
       Zugriffverletzung "[b]Schreiben von Adresse[/b]"
Wenn aber Player "ungültig" ist, dann gäbe es mit hoher Wahrscheinlichkeit schon beim Lesen einen Fehler und nicht erst bei Schreiben, zumindestens im angegebenen Speicherbereich von $00000000 bis $0000FFFF ( $00030fc0 ).
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Zugriffsverletzung nach Modulus

  Alt 21. Apr 2010, 09:08
TPlayer ist aber, laut seiner Aussage, ein Record.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#9

Re: Zugriffsverletzung nach Modulus

  Alt 21. Apr 2010, 09:16
Zitat von Luckie:
TPlayer ist aber, laut seiner Aussage, ein Record.
OK, dann kann der Fehler also nicht direkt in dieser Codezeile liegen,
es sei denn dieses Player ist ein Var/Const-Parameter einer Prozedur und der übergebene Parameter-Wert ist "ungültig".

Aber wenn sonst alles "korrekt" ist, dann kann der Fehler also nicht in dieser Codezeile stecken.

Da er ja angeblich auch Arrays verwendest:
Hast du denn schonmal die Bereichprüfung aktivert? (z.B. in den Projektoptionen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
RebellX

Registriert seit: 21. Feb 2009
8 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Zugriffsverletzung nach Modulus

  Alt 21. Apr 2010, 18:00
So, hab nochmal sichergestellt, das die Bereichsprüfung an ist (ich kann Integeroverflow etc. erzeugen und krieg nen Fehler).

Hab auch versucht, auf das Modulus zu verzichten und die Animationen (hat zwar dynamische Arrays, hatte aber funktioniert) noch mal rausgenommen.

Die Stelle mit ehemals - 1 + 4 sähe nun so aus:

Delphi-Quellcode:
    while aplayer.angle > 3 do aplayer.angle := aplayer.angle - 4;
    aplayer.angle := aplayer.angle + 3;
    while aplayer.angle > 3 do aplayer.angle := aplayer.angle - 4;
wenn ich davon die 2. Zeile auskommentiere, funzt es ohne Probleme. Wenn ich aber +3 rechne (muss als byte ja gehen, die 1. und 3. Anweisungen stellen sicher, das man im Rahmen von 0..3 bleibt), sagt er wieder Zugriffsverletzung und zeigt im CPU-Fenster auf push $00000400 oder push ebx. Die anderern beiden Fälle hab ich dabei mal auskommentieren können.

Habe noch   if not assigned(@aplayer) then exit; am Anfang eingefügt, bringt auch keine Besserung...

Und eine Int64 Variable zum Feststellen, ob es mein Speicher ist, auf den ich zugreife hat auch nichts gebracht:

  if not aplayer.Testint = test then exit; Testint und test sind Int64, test eine sehr große Konstante.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:22 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz