![]() |
Delphi-Version: 7
Stack-Overflow abfangen
Habe ein Programm das die Länge eines vorhandenen Weges von einem Starpunkt zu einem Zielpunkt berechnen soll:
X0000 00000 00000 00000 0000X Das klappt, solange in dem Weg keine "Kreise" auftreten (Abzweigungen sind kein Problem): XXX00 X00X0 X0XXX X0X0X XXX0X etwa liefert als Länge 12; Problematisch wird es sobald ein Weg vor dem Ziel einen "Kreis bildet": XXXXX X000X XXXXX X0000 XXXXX Hier kommt es zu einer Endlosschleife und dadurch zu einem Stackoverflow - den ich abfangen und stattdessen eine Fehlermeldung ausgeben möchte. Mein Code:
Delphi-Quellcode:
Aufgerufen wird das ganze durch einen Buttonclick:
class function TFelder.RestWeg(Sender: TObject; last: integer): integer;
var counter,a,b,c,d: integer; begin counter:=0; if (TFelder(Sender).Fxpos=5) and (TFelder(Sender).Fypos=5) then counter:=0 //Ziel else if (felder[TFelder(Sender).Fxpos, TFelder(Sender).Fypos-1].Ftyp<>'Weg') then counter:=11 //Falls keine Verbingung von Start zu Ziel vorhanden else begin a:=10; b:=10; c:=10; d:=10; if (TFelder(Sender).Fypos>1) and (last<>2) then //last gibt die "Richtung" an, von der gezählt wird //-> somit keine Umkehr möglich, wass abermals zu einer Endlosschleife führen würde a:=Restweg(felder[TFelder(Sender).Fxpos, TFelder(Sender).Fypos-1], 4)+1; if (TFelder(Sender).Fypos<5) and (last<>4) then b:=Restweg(felder[TFelder(Sender).Fxpos, TFelder(Sender).Fypos]+1, 2)+1; if (TFelder(Sender).Fxpos>1) and (last<>1) then c:=Restweg(felder[TFelder(Sender).Fxpos-1, TFelder(Sender).Fypos], 3)+1; if (TFelder(Sender).Fxpos<5) and (last<>3) then d:=Restweg(felder[TFelder(Sender).Fxpos+1, TFelder(Sender).Fypos], 1)+1; counter:=min(a,b); counter:=min(counter,c); counter:=min(counter,d); end; result:=counter; end;
Delphi-Quellcode:
Würde den Fehler gerne einfach mit Try ... Except ... End abfangen, und eine Fehlermeldung "Unerlaubter Weg" ausgeben - bin daran jedoch gescheitert.
procedure TForm1.Button1Click(Sender: TObject);
begin CreepLife.text:=inttostr(Tfelder.RestWeg(felder[0,0],0)); |
AW: Stack-Overflow abfangen
Lass es laufen und guck, was für eine Exception dir Delphi wirft und genau die fängst du dann in einem try-except-Block ab.
|
AW: Stack-Overflow abfangen
Oder merk dir, wo du schon überall warst und laß es garnicht erst so weit kommen. :angle2:
|
AW: Stack-Overflow abfangen
Zitat:
Habe auch schon versucht diese mit try...except aufzufangen (bzw. auch generell jede), das hat aber nicht funktioniert. Kann mir jemand sagen, wo genau das try bzw. das except in den code gehört? |
AW: Stack-Overflow abfangen
Du hast eine Rekursion programmiert. Diese definiert sich eben dadurch, dass eine Routine sich selbst aufruft. Nun darfst Du selbst überlegen, wo ein try-except-Block überall Sinn macht, oder Du beachtest himitsus Hinweis und versuchst eine Endlos-Rekursion (wirklich endlos ist sie ja nicht, wie Du gerade schmerzvoll erfährst) im Vorfeld zu vermeiden, was die sauberere Lösung wäre.
|
AW: Stack-Overflow abfangen
uebergib in jeder rekursion die rekusrionstiefe mit, und brich frühzeitig ab (z.b. tiefe 30)
|
AW: Stack-Overflow abfangen
Zitat:
|
AW: Stack-Overflow abfangen
Zitat:
|
AW: Stack-Overflow abfangen
Mal abgesehen davon, dass es extrem viel länger dauert, wenn man sich nicht merkt wo man schon war...
|
AW: Stack-Overflow abfangen
Bedenkt aber, daß man auch etwas mehr Speicher benötigt, wenn man sich den Weg merkt, da dieses für jede Rekusrionsebene einzeln gepeichert (kopiert und erweitert) werden muß.
Also vorallem, wenn man es mit auf den Stack legen würde. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:08 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