AGB  ·  Datenschutz  ·  Impressum  







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

Zugriffsverletzung

Ein Thema von Chii · begonnen am 30. Jun 2006 · letzter Beitrag vom 30. Jun 2006
Antwort Antwort
Chii

Registriert seit: 30. Jun 2006
4 Beiträge
 
#1

Zugriffsverletzung

  Alt 30. Jun 2006, 10:10
Hallo!

Ich wollte ein Sudoku-Rätsel-Programm schreiben, wo der PC selber per random ein Sudoku erstellt. Hierzu habe ich erstmal die erste Zeile generiert und wollte diese dann ausgeben lassen.

Dabei wurde mir folgender Fehler angezeigt:
Zugriffsverletzung bei 0x0040597d: Schreiben von Adresse 0x00030cd4. Prozess angehalten.

Mein Quellcode:

Delphi-Quellcode:
procedure TForm1.BTErstellenClick(Sender: TObject);
var i,a:integer;
begin
 setlength(sudoku,80);
 for i:=0 to 80 do
  sudoku[i]:=0;
 randomize;

 a:=random(9)+1;
 sudoku[0]:=a;

 zahl0.Text:=inttostr(sudoku[0]);

 a:=random(9)+1;
 while a=sudoku[0] do
  a:=random(9)+1;
 sudoku[1]:=a;

 zahl1.Text:=inttostr(sudoku[1]);

 a:=random(9)+1;
 while (a=sudoku[0]) or (a=sudoku[1]) do
  a:=random(9)+1;
 sudoku[2]:=a;

 zahl2.Text:=inttostr(sudoku[2]);

 a:=random(9)+1;
 while (a=sudoku[0]) or (a=sudoku[1]) or (a=sudoku[2]) do
  a:=random(9)+1;
 sudoku[3]:=a;

 zahl3.Text:=inttostr(sudoku[3]);

 a:=random(9)+1;
 while (a=sudoku[0]) or (a=sudoku[1]) or (a=sudoku[2]) or (a=sudoku[3]) do
  a:=random(9)+1;
 sudoku[4]:=a;

 zahl4.Text:=inttostr(sudoku[4]);

 a:=random(9)+1;
 while (a=sudoku[0]) or (a=sudoku[1]) or (a=sudoku[2]) or (a=sudoku[3])
        or (a=sudoku[4]) do
  a:=random(9)+1;
 sudoku[5]:=a;

 zahl5.text:=inttostr(sudoku[5]);

 a:=random(9)+1;
 while (a=sudoku[0]) or (a=sudoku[1]) or (a=sudoku[2]) or (a=sudoku[3])
        or (a=sudoku[4]) or (a=sudoku[5]) do
  a:=random(9)+1;
 sudoku[6]:=a;

 a:=random(9)+1;
 while (a=sudoku[0]) or (a=sudoku[1]) or (a=sudoku[2]) or (a=sudoku[3])
        or (a=sudoku[4]) or (a=sudoku[5]) or (a=sudoku[6]) do
  a:=random(9)+1;
 sudoku[7]:=a;

 a:=random(9)+1;
 while (a=sudoku[0]) or (a=sudoku[1]) or (a=sudoku[2]) or (a=sudoku[3])
        or (a=sudoku[4]) or (a=sudoku[5]) or (a=sudoku[6]) or (a=sudoku[7]) do
  a:=random(9)+1;
 sudoku[8]:=a;
end;
Nach "zahl5.text:=inttostr(sudoku[5]);" wird der Fehler angezeigt, wenn ich diese Zeile ans Ende setze, läuft er die anderen Zeilen problemlos durch und zeigt dann wieder den Fehler an. Wenn ich die Zeile komplett weglasse und 2mal auf den Button klicke, dann kommt der Fehler ebenfalls. Sudoku ist ein global vereinbarter array of integer.

Kann mir jemand bitte helfen?

THX im Voraus!
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#2

Re: Zugriffsverletzung

  Alt 30. Jun 2006, 10:14
Hallo,

gleich am Anfang:
Delphi-Quellcode:
setlength(sudoku,80);
for i:=0 to 80 do
  sudoku[i]:=0;
Du erstellst ein Array mit der Länge 80, also von 0 bis 79. Dann greifst Du aber auf das Element #80 zu, das nicht existiert.

Gruß
xaromz

Edit: Herzlich Willkommen!
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
877 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Zugriffsverletzung

  Alt 30. Jun 2006, 10:16
Delphi-Quellcode:
setlength(sudoku,80);
for i:=0 to 80 do
- müsste die Länge nicht 81 sein? Ich glaube zwar nicht unbedingt, dass der Fehler daher kommt, aber ein Anfang wärs
  Mit Zitat antworten Zitat
Benutzerbild von ste_ett
ste_ett

Registriert seit: 10. Sep 2004
Ort: Dülmen
464 Beiträge
 
Delphi 7 Professional
 
#4

Re: Zugriffsverletzung

  Alt 30. Jun 2006, 10:40
Delphi-Quellcode:
  for i := Low(ArrayName) to High(ArrayName) do
  begin
    ...
  end;
Das wäre eine Möglichkeit, solche Fehler nicht zu wiederholen.

Bei dynamsichen Arrays ist Low() imemr 0, da kann man sich das dann sparen und gleich 0 nutzen.
Stefan
"Geht nicht!" ist keine Fehlerbeschreibung und "Hab ich schon versucht!" keine Antwort!

Hey, it compiles! Ship it!
  Mit Zitat antworten Zitat
Chii

Registriert seit: 30. Jun 2006
4 Beiträge
 
#5

Re: Zugriffsverletzung

  Alt 30. Jun 2006, 10:41
ihr werdet lachen, aber anscheinend war es das! <3 delphi
  Mit Zitat antworten Zitat
Chii

Registriert seit: 30. Jun 2006
4 Beiträge
 
#6

Re: Zugriffsverletzung

  Alt 30. Jun 2006, 10:58
so... nun hab ich die zweite zeile hinzugefügt und starte es - was passiert? delphi hängt sich auf!
wenn ich die per haltestops durchgehe, gibt er mir ein ergebnis aus.
was kann ich machen?!
  Mit Zitat antworten Zitat
Benutzerbild von ste_ett
ste_ett

Registriert seit: 10. Sep 2004
Ort: Dülmen
464 Beiträge
 
Delphi 7 Professional
 
#7

Re: Zugriffsverletzung

  Alt 30. Jun 2006, 11:08
Evtl. hast du eine Endlosschleife drin.
Prüfe mal im Debugger, ob alle Schleifen korrekt durchlaufen werden.
Stefan
"Geht nicht!" ist keine Fehlerbeschreibung und "Hab ich schon versucht!" keine Antwort!

Hey, it compiles! Ship it!
  Mit Zitat antworten Zitat
Chii

Registriert seit: 30. Jun 2006
4 Beiträge
 
#8

Re: Zugriffsverletzung

  Alt 30. Jun 2006, 11:17
der debugger zeigt mir keine fehler an, es funktioniert ja auch alles, wenn ich mit haltepunkten durchgehe.
  Mit Zitat antworten Zitat
Sidorion

Registriert seit: 23. Jun 2005
403 Beiträge
 
#9

Re: Zugriffsverletzung

  Alt 30. Jun 2006, 12:01
Ich will Dich nicht enttäuschen, aber so kommst Du leider nicht weit.
Als Speicher für die Felder würde ich Dir ein Array [0..8,0..8] of Byte vorschlagen.
Das Füllen dieses Arrays würde ich mit Backtracking algorithmus tun.
Die Bedingung dafür dass eine best. Zahl in ein Feld passt, ist ja, dass sie Zahl weder in der selben Reihe, noch in der selben Spalte, noch im selben Feld schonmal steht. Dafür würd ich mir ne funktion schreiben ala ZahlGültig(Zeile, Spalte, Zahl): Boolean.
Jetzt kannst Du folgendermassen vorgehen:
Du gehst dein Array durch, und versuchst das nächste Feld zu füllen (und zwar testest Du zufällig die Zahlen 1-9 und die erste, die geht schreibst Du rein (und merk dir für jedes Feld, welche Zahl schon getestet wurde). KannstDu nun ein Feld mit keiner Zahl füllen (alle neun negativ getestet), musst Du ein Feld zurück, und dort ndie nächste Zahl testen. geht das wieder nicht, dann wieder ein Feld zurück.
Das ganze kannst Du iterativ oder rekursiv lösen, wobei Rekursiv einfacher wäre, wegen dem Merken der getesteten Zahlen, sprich:
Delphi-Quellcode:
SetzeZahl(Zeile, Spalte): Boolean;
wiederhole
 würfle Zahl aus Vorrat und streiche diese aus Vorrat.
 prüfe zahl
solange bis vorrat leer oder prüfung erfolgreich
wenn prüfung erfolgreich,
dann begin
  schreibe Zahl in Array
  wenn Zeile und Spalte <8
  dann begin
   wenn spalte<8
   dann Ergebnis=SetzeZahl(Zeile, Spalte+1)
   sonst Ergebnis=setzeZahl(Zeile+1, 0)
  sonst Ergebnis=Ja
sonst ergebnis=nein
Manchmal sehen Dinge, die wie Dinge aussehen wollen mehr wie Dinge aus, als Dinge
<Esmerelda Wetterwachs>
  Mit Zitat antworten Zitat
Antwort Antwort


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 05:09 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