Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Unlösbares Problem? (https://www.delphipraxis.net/154303-unloesbares-problem.html)

Lotus 5. Sep 2010 14:05

Unlösbares Problem?
 
Hallo,

ich programmiere zur Zeit mein eigenes Pokerspiel, es ist wahrscheinlich alles nicht sehr intelligent gelöst (mit Arrays und kein OOP) aber das reicht mir erstmal für den Anfang.

Jetzt aber mein Problem:

Ab und zu kommt eine EAccessViolation, also ein Zugriffsfehler auf den Speicher vor... und das Problem ist, dass es wirklich nur selten so ist!!!

Hier die Code-Zeile, die mir Delphi als falsch makiert:
Delphi-Quellcode:
for i:=0 to high(KartenArray) do begin
if (KartenArray[i].KartenZiffer = KartenArray[i+1].KartenZiffer)
....
end;
Naja, jetzt dachte ich mir, okay... ist ja logisch wenn ich in einem Array was von 0-5 geht durchgehe und dann auf [i+1] zugreifen will, das dann ein Fehler auftaucht.. aber die Frage ist jetzt, wieso taucht der Fehler nur manchmal auf?

Ich hab mir eine Endlosschleife gebastelt in dem immer wieder simuliert wird, wie das Spiel neugestartet wird.. Gleichzeitig nen Zaehler mitlaufen lassen... Die unterschiedlichsten Werte sind dafür rausgekommen:
579,190,932,293,1258,119,6599,537,15353....

Das kann doch nicht sein?

Ich teste es gerade mit der Schleife bis zu high -1 und es scheint gut zu laufen.. aber wieso taucht der Fehler oben nur so selten auf?

himitsu 5. Sep 2010 14:25

AW: Unlösbares Problem?
 
Nja, wenn zufällig hinter dem Array etwas liegt, welches hier rein zufällig auch noch paßt, dann gibt es natürlich keinen Zugriffsfehler.

Delphi-Quellcode:
for i:=0 to high(KartenArray) - 1 do begin
.


Ich kann es allen immer wieder nur nochmal sagen:
Man sollte mal in den Projektoptionen die Überlauf- und die Bereichprüfung anschalten.

hboy 5. Sep 2010 14:33

AW: Unlösbares Problem?
 
Ob ein Fehler kommt oder nicht hängt meines Erachtens nach davon ab, ob hinter dem Speicherblock noch ein Stück Speicherbereich kommt, das schon von deinem Programm alloziiert wurde. Jenachdem, wie die Speicherverwaltung gelöst ist, kann also nach dem array noch eine andere Datenstruktur oder überschüssiger Speicher liegen, dann sind Adresszeiger in diesen Raum gültig und die Fehlermeldung bleibt aus. Zu Fehlverhalten kann es trotzdem kommen, etwa wenn man ein dynamisches Array ausliest.

edit: himitsu war mal wieder schneller ;-)

Lotus 5. Sep 2010 15:40

AW: Unlösbares Problem?
 
Okay danke für die schnelle Erklärung... allerdings habe ich in den Projektoptionen die Option angeschalten!

himitsu 5. Sep 2010 16:07

AW: Unlösbares Problem?
 
Dann dürfte man bei sowas nicht außerhalb der Arraygrenzen zugreifen können. :gruebel:

mkinzler 5. Sep 2010 16:16

AW: Unlösbares Problem?
 
Und zu High() gehört Low()

himitsu 5. Sep 2010 17:12

AW: Unlösbares Problem?
 
Dynamische Arrays fangen eh immer nur bei 0 an. :angel:

mkinzler 5. Sep 2010 17:15

AW: Unlösbares Problem?
 
Vielleicht kommt man aber auf deie Idee das einmal zu ändern.

himitsu 5. Sep 2010 17:28

AW: Unlösbares Problem?
 
Dann wäre Delphi aber nicht mehr abwärtkompatibel. :tongue:
(aus diesem Grund schleppen wir ja auch schon seit unzähligen Jahren diese 1 bei den Strings mit uns rum)

SirThornberry 5. Sep 2010 17:45

AW: Unlösbares Problem?
 
@Lotus: Bitte gib deinem Thema, entsprechend den Forenregeln, einen aussagekräftigen Titel. Der jetzige Titel sagt rein gar nichts über dein Problem aus. :)

alzaimar 5. Sep 2010 20:42

AW: Unlösbares Problem?
 
Sagt mal, die Bereichsprüfung funktioniert auch bei dynamischen Arrays?

himitsu 5. Sep 2010 22:07

AW: Unlösbares Problem?
 
Diese arbeitet nur bei dynamischen Arrays. (String = aufgemotztes dyn. Array)


Bei statischen Arrays meldet sich der Compiler mit einer Fehlermeldung, egal ob die Bereichsprüfung an oder aus ist.
(mit Ausnahme der [0..0], welche ohne Prüfung durchgeht)

hboy 6. Sep 2010 09:36

AW: Unlösbares Problem?
 
Delphi-Quellcode:
type
  TTestArray = Array of Byte;
  PTestArray = ^TTestArray;

procedure TForm1.Button1Click(Sender: TObject);
var
  q : PTestArray;
begin
  q^[10] := 1;
end;
Zugegebenermaßen ist das etwas weit hergeholt, aber hier kommt gleich eine handfeste Zugriffsverletzung. Nicht, dass der code einen Sinn hätte, aber er zeigt zumindest in Delphi 7, dass die Bereichsprüfung erst nach dem Anlegen eines Feldes zu greifen scheint. Sobald Speicher dafür reserviert oder ein anderes Feld zugewiesen wurde, kommen range check - Fehler.

mkinzler 6. Sep 2010 09:53

AW: Unlösbares Problem?
 
Eien Dynamischer Array ist schon ein Zeiger

hboy 6. Sep 2010 22:57

AW: Unlösbares Problem?
 
richtig, die zusätzliche Umschreibung war unnötig, aber auch mit dem direkten Zuweisen einer Zelle von einem nicht initialisierten array gibt es unmittelbar eine Zugriffsverletzung, da das Array dann bei Adresse 0x00000000 beginnt. Ebensogut könnte man TTestArray(nil) zuweisen, doch dann kommt der range check error - das ist, was mich stört.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz