Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Jul 16, 2025 23:14

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Mi Jun 18, 2008 15:05 
Offline
DGL Member

Registriert: Sa Sep 20, 2003 10:07
Beiträge: 6
Wohnort: Damage Inc.
Hi!

Ich bin derzeigt dabei, mit Freepascal bzw. Lazarus und SDL eine Art Ballerspiel mit Autos zu schreiben. Bin auch schon recht weit gekommen und funktioniert alles super. Ich hab da nur ein seltsames Problem. Meine Map besteht aus einem zweidimensionalen, dynamischen Array. Beim initialisieren der Karte rufe ich den Befehl
Code:
  1. SetLength(tile,SizeX,SizeY);

auf. tile ist dabei ein "array of array of TTile". Folgendes funktioniert:
Code:
  1. SetLength(tile,80,80);

Aber bei folgendem stürzt das Programm ab...und zwar genau in der Zeile von SetLength:
Code:
  1. SetLength(tile,40,40);

Ich kann mir das Verhalten nicht erklären. Könnt ihr mir da evtl. weiterhelfen? Hattet ihr so ein Problem auch schon mal?

Gruß!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 18, 2008 15:37 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich wusste bis jetzt noch nichteinmal, dass SetLength drei Parameter unterstützt. Warum er mit 80, 80 funktioniert und mit 40, 40 nicht, weiss ich nicht, aber es gibt alternativen:

Notfalls musst du halt entweder mit einem Pointer arbeiten, einem eindimensionalen Array (und dann die Koordinaten umrechnen mit I = Y*W + X (wobei W die Breite der Karte ist und I der Index im eindimensionalen Array) oder du machst es dir ganz einfach und initialisierst dein Array so:
Code:
  1. SetLength(tile, 40);
  2. for I := 0 to 39 do
  3.   SetLength(tile[I], 40);


Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 18, 2008 15:48 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Bei Setlength kann man so viele Längenparameter angeben wie ein Array Dimensionen hat. Das mache ich schon immer so und rein theoretisch dürfte an einer solchen Stelle garkein Fehler auftreten. Ich denke dein Fehler liegt an einer anderen Stelle, und das Programm springt dann eher "zufällig" bei dieser Zeile raus. Also einfach mal im Debugger schaun wo das Problem wirklich liegt, vor allem der Aufrufstack und dort überwachte Variablen sollten die Lösung schnell finden lassen.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 18, 2008 16:12 
Offline
DGL Member

Registriert: Sa Sep 20, 2003 10:07
Beiträge: 6
Wohnort: Damage Inc.
Danke erstmal für die Antworten!
Ich kann mir halt einfach nicht erklären, wo der Fehler ansonsten liegen könnte...mit SetLength(tile,16,16) funktioniert es nämlich z.B. auch...es scheint nur halt bei ca. 40 einen Bereich zu geben, der das Programm zum Absturz bewegt....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 18, 2008 16:17 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Das ist eigentlich unmöglich. Evtl. machst du irgendwo einen Zugriff auf einen Bereich ausserhalb der Grenzen, dass es mit den anderen Werten geht ist dann eher purer Zufall. Also Debugger anschmeissen und Fehler finden.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 18, 2008 17:01 
Offline
DGL Member

Registriert: Sa Sep 20, 2003 10:07
Beiträge: 6
Wohnort: Damage Inc.
Also ich bin grad sehr verwirrt. Mit eingeschaltetem Debugger:

SetLength(tile,10,10); -> funktioniert

SetLength(tile,32,32); -> funktioniert

SetLength(tile,80,80); -> funktioniert

SetLength(tile,100,100); -> funktioniert

SetLength(tile,40,40);
"Project raised exception class 'External: SIGSEGV'."
"Ausführung angehalten

Adresse: $0040A0FE
Prozedur: SYSTEM_SYSGETMEM_FIXED$LONGINT$$POINTER
Datei:

(TODO: Assembler-Ansicht an dieser Stelle"

Überall, wo ich auf Elemente des Array Zugreife mach ich das z.B. so:
Code:
  1.  
  2. for x := 0 to SizeX-1 do
  3.   for y := 0 to SizeY-1 do
  4.   begin
  5.     // blabla
  6.   end;
  7.  


SizeX und SizeY werden nur beim Initialisieren der Karte festgelegt und auch sonst nirgens geändert. Was kann das denn sein? Ich weiß echt nicht weiter...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 19, 2008 08:25 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Das Problem ist, dass man Dir so nicht helfen kann. Denn der Code, denn Du uns zeigst ist völlig in Ordnung. Hier ist es schon häufig vorgekommen, dass man zwar Code zu sehen kriegt, aber dass der eigentliche Fehler ganz woanders lag und der angezeigte Code nur mittelbar damit was zu tun hatte. Es ist, als ob Du sagst: "Irgendwo im Mittelmeer schwimmt ein toter Fisch". Aber Du zeigst uns nur 4 Quadratmeter spanischen Strand. Wie sollen wir je den toten Fisch lokalisieren?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 19, 2008 08:56 
Offline
DGL Member

Registriert: Sa Sep 20, 2003 10:07
Beiträge: 6
Wohnort: Damage Inc.
Moin!
Ich verstehe ja, was du meinst. Aber ich kann euch ja nicht meinen ganzen Quellcode posten...das sind ja mehrere 1000 Zeilen...und so lange ich selbst nicht weiß, wo die relevanten Stellen im Code sind....woher soll ich dann wissen, was ich euch zeigen sollte?
Also ich bin mir sicher, dass ich auf das Array immer nur innerhalb der erlaubten Grenzen zugreife...was könnten denn sonst noch für Probleme mit dynamischen Arrays und SetLength auftreten?
Gruß!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 19, 2008 09:24 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Du solltest das Problem evtl. auch nicht nur in der Nähe deines Arrays suchen. Ich habe es schon häufiger mal gehabt, dass ich ein Stück Code geschrieben habe und an einer vollkommen anderen Stelle ist zu einem Fehler gekommen. Invalid Pointeroperations äußern sich teilweise sogar erst dann, wenn man die Anwendung beendet. Da entstehen Zeitverzögerungen von Sekunden oder Minuten.

Als Beispiel um das zu verdeutlichen was ich meine. Du hast ein Array und direkt im Anschluss an das Array liegen die Daten einer Klassen im Speicher. Wenn du jetzt das Array befüllst und nicht auf deine Grenzen achtest, dann schreibst du gnadenlos in den Bereich der Klasse. Du bekommst aber beim Befüllen des Arrays keinen Fehler sondern erst dann, wenn du das nächste mal wieder auf die Klasse zugreifen willst. Oder es befinden sich sinnlose Werte innerhalb der Klasse. Dann knallt es nicht beim Zugriff auf die Klasse selbst sondern beim Zugriff auf eine Unterklasse der Klasse. Wie die Daten im Speicher liegen verwaltet der Speichermanager und die Daten müssen nicht mal etwas miteinander zu tun haben.

Ich würde dir Empfehlen alle möglichen Prüfungen zu aktivieren. Bereichsrüfung. Überlaufprüfung etc. Keine Ahnung was FPC dort alles bietet. Außerdem würde ich dir raten keine Magix Numbers zu verwenden. Bei Zugriff auf Arrays arbeite ich persönlich grundsätzlich nur noch mit Length bzw. High. Mit wenigen Ausnahmen. Falls du Pointer verwenden solltest solltest du auch wirklich sehr genau darauf achten was du tust. Dort gibt es so gut wie keine wirklichen Prüfungen. Vor allem achte darauf, dass du nicht irgendwann mal die Pointervariable anstelle des Inhaltes benutzt. FillChar zum Beispiel möchte einen Speicherbereich übergeben haben. Wenn du einen Pointer erstellst und diesen nicht dereferenziert übergibst, dann überschreibst du dir deinen Stack. Dort liegen Sprungadressen, Variablen etc. Die Liste der möglichen Probleme ist lang.

Sonst kann ich allen Anderen nur recht geben. Da können wir dir nicht sagen wo das Problem liegt, denn SetLength ist normal ein sehr unkritischer Teil. Evtl schaust du dir selber noch mal den Code an der vorher ausgeführt wird. Vielleicht fällt dir da ja schon etwas auf weil du später mal einen Wert verändert hast etc.

Zu mindest spricht das Verhalten auch für etwas was ich oben erwähnt habe. 40x40 liefert einen Fehler. 100x100 geht. Ich denke 100x100 ist zu groß um in einen aktuellen block zu passen und landet deswegen woanders im Speicher. 40x40 wird dann vermutlich an einer Speicherstelle liegen an der es zu Problemen kommt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 19, 2008 09:27 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Fest steht, dass bei Dir irgendetwas beim Speicher anfordern geschieht. Benutzt Du Objekte? Mögliche Fehlerquellen sind Objekte, die nocht nicht erzeugt (oder schon gelöscht) worden sind und auf die zugegriffen wird. Es gibt seltene Fälle, wo der Compiler so etwas nicht mitkriegt. Und dann crasht es erst beim nächsten mal, wo in diesem Bereich wieder Speicherplatz gebraucht wird, oder wenn Du irgendwo irrtümlich vorher Finalize benutzt hast.

Das zweite Fakt ist, dass der wirkliche Fehler irgendwo VORHER sein muss. Wenn der Fehler mitten im Programm oder erst am Ende auftritt, haben wir natürlich Pech gehabt.

Die erfolgversprechendste Technik dabei ist, den Fehler so einzukreisen, dass der zu untersuchende Code minimal wird. Ist schwer, ich weiß. Soweit ich weiß, hat jeder Programmierer da eigene Techniken, einfach weil jeder eine bevorzugte Programmstruktur hat. Das heißt, wie hoch Deine Chancen sind, den Fehler zu finden, hängt auch maßgeblich davon ab, wie gut strukturiert dein Programm ist.

Ich selber würde in einem Fall, wo ich gar keinen Hinweis darauf habe, wo genau ich suchen muss, mir die Mühe machen, das Programm von Anfang an mit dem Debugger zu durchkämmen. Das heißt, auch alle wichtigen Variablen zu überwachen. Manchmal hat man dabei auch einige wertvolle Aha-Erlebnisse.

Ich arbeite mit Delphi, und wenn ich einem Programm den letzten Schliff verpasse, ist eine der Vorbereitungsschritte, dass ich den "Meckermodus" einschalte. Da kommt meistens auch einiges heraus.

Aber weißt Du, was mir wirklich am besten hilft? Ich suche mir eine mitleidige Seele, die mir zuhört, bevorzugterweise jemand, der ein guter Analytiker ist aber möglichst keine Ahnung vom Programmieren hat. Dann bin ich nämlich gezwungen, dem ganz genau den Programmablauf zu schildern. Es ist zwar kaum zu glauben, aber das ist die erfolgreichste Methode, die ich kenne. Damit habe ich Fehler gefunden, wo ich auch mit Debuggen keinen Erfolg hatte.
Traude

NACHTRAG: Mist! Lossy war schneller :wink:

NOCH EIN NACHTRAG: Ich hatte mal einen Kollegen, der suchte tagelang nach einem Fehler. Es war ein Datenbankprogramm. Schließlich fand er heraus, dass er sich in der falschen Datenbank befunden hat. :D


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 19, 2008 15:45 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ansonsten, was mir gerade einfällt: Das Debugging mit FPC unter Windows ist alles andere als berauschend, das muss ich leider wirklich sagen. Eine gute idee ist es daher, mal vor und nach dem SetLength-Befehl ein WriteLn zu setzen mit unterschiedlichem Inhalt. Siehst du nur das erste, weisst du, dass er wirklich bei SetLength crasht. Siehst du beide weisst du, dass er ganz woanders crasht und dir nur die falsche zeile anzeigt (dann wirds ekelhaft :wink:) . Siehst du nur das zweite.... Nun, dann läuft irgendetwas wirklich schief :D

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 19, 2008 16:07 
Offline
DGL Member

Registriert: Sa Sep 20, 2003 10:07
Beiträge: 6
Wohnort: Damage Inc.
Hi!
Das hab ich schon gemacht...er crasht definitiv in dieser Zeile...
Ich benutze übrigens den Debugger, der bei Lazarus dabei ist. Wenn ich Variablen überwache, dann haben die eigentlich alle den richtigen Wert. Manchmal stehen seltsamerweise drei Fragezeichen (???) davor und ich weiß nicht so recht, was da bedeutet. Aber auf jeden Fall haben die Fragezeichen nichts direkt mit dem Absurz zu tun, weil sie bei manchen Zahlenpaaren da stehen, bei denen das Programm trotzdem funktioniert. Also es gibt keinen direkten Zusammenhang zwischen den Fragezeichen und den Programmabstürzen.
Gruß!


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: Majestic-12 [Bot] und 14 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.033s | 18 Queries | GZIP : On ]