![]() |
Debuggen einer Schleife
Guten Abend DPler,
langsam glaube ich, dass mich Delphi trollen will. Innerhalb einer Schleife kommt es regelmäßig zu einer AV. Jedoch ist das komische, dass sie immer an einer anderen Stelle auftritt. Mal nach der 10.000 Iteration, mal "erst" nach der 14.000 :pale: Mit einigen try-except-Blöcken konnte ich nun nachvollziehen, dass es *scheinbar* an dem Constructor eines Objekts liegt.
Delphi-Quellcode:
Nur das (für mich) Komische ist, dass der try-except-Block in dem constructor nicht ausgelöst wird
type
FeldArray1D = Array of TFeld; var folgeZustand, Zustand: TStack; aArray: FeldArray1D Feld: TFeld; begin for y:=0 to High( aArray ) do try folgeZustand.push( TZustand.create( without(aArray, y), Feld, TZustand( Zustand.top ) ) ); except showmessage('Fehler bei Zustand.create'); // Wird ausgelöst end; end;
Delphi-Quellcode:
Kann es evtl. sein, dass nur eine begrenzte Anzahl an Objekten erstellt werden kann ? Das ganze wird wie gesagt mehrere Tausend Mal aufgerufen. :shock:
constructor TZustand.create(const pBrennt: FeldArray1D; const pGeloescht: TFeld;
const pVorgaenger: TZustand); begin try lVerbrannt := pBrennt; fGeloescht := pGeloescht; zVorgaenger := pVorgaenger; except showmessage('Fehler in create'); // Keine Reaktion end; end; Oder gibt es einen ganz simplen Trick, mit dem ich per debugger an das Problem herangehen kann ? Denn wenn das ganze mal wieder crashed, kommt nur die AV-Meldung und das CPU-Fenster öffnet sich - nicht die gecrashte Quellcodezeile :roll: |
AW: Debuggen einer Schleife
Der Fehler liegt offensichtlich nicht im Konstruktor, sondern woanders, deshalb hilft dir auch der Try-Except-Block dort nichts. Vermutlich zerschießt dir irgendwas den Speicher oder es wird auf eine Struktur zugegriffen, die schon freigegeben wurde. Mehr kann man dazu nicht sagen, ohne den kompletten Source-Code zu haben.
Wie viele Objekte man anlegen kann ist nur durch den Arbeitsspeicher begrenzt. Aber wenn der voll ist, dann kommt keine AV, sondern eine andere Exception, deren genauen Namen ich vergessen habe. Im Zweifelsfall debugge ich solche Fehler, indem ich so lange alles auskommentiere, bis der Fehler nicht mehr auftritt. |
AW: Debuggen einer Schleife
Das ist ein typisches Einsatzgebiet für FastMM. Das sagt dir im FullDebugMode evtl. sofort wo das Problem liegt. ;-)
|
AW: Debuggen einer Schleife
Zitat:
|
AW: Debuggen einer Schleife
Zitat:
Delphi-Quellcode:
Es gibt auch noch Dinge wie EurekaLog und Co., welche beim Suchen der Fehler helfen.
try
... except on E: Exception do begin E.Message := E.ClassName + ' in Xyz: ' + E.Message; // hier kann man z.B. auch den Index der Schleife erwähnen raise; // oder notfalls ShowException(E, nil); und Dergleichen end; end; Wenn sich der Fehler absolut nicht finden lässt, dann kann man es auch mal so versuchen.
Delphi-Quellcode:
try
// mach was except on E: Exception do begin ShowException(E, nil); // <<<<<< hier ein Haltepunkt hin // mach es nochmal (hoffentlich tritt der Fehler nochmal auf und man kann sich dabei langsam hindurchdebuggen) end; end; |
AW: Debuggen einer Schleife
Delphi-Quellcode:
Und wie ich Bandwurmcode hasse ;-) (schlecht lesbar, fehlerbehaftet, buäh), also schreib das mal übersichtlicher und formatiere deinen Code nächstes Mal zumindest ansatzweise, danke.
...
for y:=0 to High(aArray) do folgeZustand.push ( TZustand.create ( without(aArray, y), Feld, TZustand(Zustand.top) /// <<---- ist 'Zustand' instantiiert? ) ); end;
Delphi-Quellcode:
Vielleicht ist das ja nun besser lesbar. Und wenn Zustand tatsächlich undefiniert ist (vielleicht sollte das ja eigentlich 'folgeZustand.Top' heißen, dann hättest Du auch deinen Fehler.
type
FeldArray1D = Array of TFeld; var folgeZustand, Zustand, zustandTop: TStack; aArray, subArray: FeldArray1D Feld: TFeld; begin zustandTop := TZustand(Zustand.top); // Einmal vor der Schleife gemerkt, reicht. for y:=0 to High(aArray) do begin subArray := Without(aArray,y); neuerZustand := TZustand.create(subArray, Feld, zustandTop); folgeZustand.push(neuerZustand); end; end; |
AW: Debuggen einer Schleife
Zitat:
Aber hier weiß ja keiner was Zustand, Zustand.Top oder Without eigentlich machen. Allerdings ist das zum Debuggen grunstäzlich erstmal genau richtig gedacht. - So kann man eventuell mitbekommen wo, in der Schlange, es nun genu knallt. - kann auch jeden Teil auch mit eigenen Try-Excepts testweise umgeben - und vorallem kann man die Rückgabewerte testweise mal prüfen - - if Assigned - - über eine Haltepunkt-Bedingung - - kann sich im Except den wert der zwischengespeicherten Rückgaben ansehn - - usw. |
AW: Debuggen einer Schleife
Zitat:
Falls Codeteile nicht weggelassen wurden. |
AW: Debuggen einer Schleife
Erst einmal Danke für die vielen Antworten und Entschuldigung meinerseits für die etwas .. wirre Frage.
Zitat:
Nachdem es dann wieder eingeschaltet war, kam nicht mehr das CPU-Fenster, sondern er sprang in eine Methode - die der constructor aufruft. Zitat:
Ziel des ganzen war es jedenfalls, aus einem Zustand (etwa die Stellung auf einem Schachbrett) alle möglichen folge-Zustände zu ermitteln - und die daraus folgenden. Dem constructor
Delphi-Quellcode:
function without(var aFeldArray: FeldArray1D; aPos: Integer): FeldArray1D;
var i, b: Integer; begin SetLength( result, High( aFeldArray ) ); b := 0; for i:=0 to High( aFeldArray ) do begin if not (i = aPos) then begin result[b] := aFeldArray[i]; // diese Zeile Inc( b ); // mit dieser vertauscht end; end; end; Zitat:
|
AW: Debuggen einer Schleife
Nicht obwohl, sondern weil du diese komische Exceptionbehandlung da so reingefriemelt hast, bringt dir das nichts.
Exceptions nur behandeln, wenn ich dafür eine Ausweichmöglichkeit habe. Einfach nur einen nichtssagenden Text anzeigen ist keine. Beispiel: Eine simple Berechnung
Delphi-Quellcode:
Beim Aufruf von
function f( const x : Extended ) : Extended;
begin Result := 1/x; end;
Delphi-Quellcode:
wird die Exception
y := f(0);
![]() Na und? Wenn der erfolgreiche Ablauf von dem Wert abhängig ist, dann ist hier wohl ein Fehler passiert und der restliche Ablauf ist somit nicht mehr zu gewährleisten. Stellen wir uns ein anderes Szenario mit der gleichen Funktion vor. Die Funktion soll grafisch dargestellt werden. Jetzt ticken die Uhren anders
Delphi-Quellcode:
x := -1;
while x <= 1 do begin try y := f( x ); DrawPoint( x, y ); except on E: EDivByZero do NoDataFor( x ); end; x := x + 0.1; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:45 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