AGB  ·  Datenschutz  ·  Impressum  







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

Stack-Overflow abfangen

Ein Thema von Sinthuor · begonnen am 14. Aug 2011 · letzter Beitrag vom 16. Aug 2011
Antwort Antwort
Seite 1 von 2  1 2      
Sinthuor

Registriert seit: 14. Aug 2011
3 Beiträge
 
#1

Stack-Overflow abfangen

  Alt 14. Aug 2011, 23:07
Delphi-Version: 7
Habe ein Programm das die Länge eines vorhandenen Weges von einem Starpunkt zu einem Zielpunkt berechnen soll:
X0000
00000
00000
00000
0000
X
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
X
000X
XXXXX
X
0000
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:
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;
Aufgerufen wird das ganze durch einen Buttonclick:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
CreepLife.text:=inttostr(Tfelder.RestWeg(felder[0,0],0));
Würde den Fehler gerne einfach mit Try ... Except ... End abfangen, und eine Fehlermeldung "Unerlaubter Weg" ausgeben - bin daran jedoch gescheitert.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

AW: Stack-Overflow abfangen

  Alt 14. Aug 2011, 23:29
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.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#3

AW: Stack-Overflow abfangen

  Alt 14. Aug 2011, 23:36
Oder merk dir, wo du schon überall warst und laß es garnicht erst so weit kommen.
$2B or not $2B
  Mit Zitat antworten Zitat
Sinthuor

Registriert seit: 14. Aug 2011
3 Beiträge
 
#4

AW: Stack-Overflow abfangen

  Alt 14. Aug 2011, 23:47
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.
Ist eine Exception der Klasse EStackOverflow.
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?
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#5

AW: Stack-Overflow abfangen

  Alt 14. Aug 2011, 23:57
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.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#6

AW: Stack-Overflow abfangen

  Alt 15. Aug 2011, 00:40
uebergib in jeder rekursion die rekusrionstiefe mit, und brich frühzeitig ab (z.b. tiefe 30)
  Mit Zitat antworten Zitat
Sinthuor

Registriert seit: 14. Aug 2011
3 Beiträge
 
#7

AW: Stack-Overflow abfangen

  Alt 15. Aug 2011, 02:20
uebergib in jeder rekursion die rekusrionstiefe mit, und brich frühzeitig ab (z.b. tiefe 30)
Das war eine super Lösung für mich. Vielen Dank!
  Mit Zitat antworten Zitat
FredlFesl

Registriert seit: 19. Apr 2011
293 Beiträge
 
Delphi 2009 Enterprise
 
#8

AW: Stack-Overflow abfangen

  Alt 15. Aug 2011, 07:00
uebergib in jeder rekursion die rekusrionstiefe mit, und brich frühzeitig ab (z.b. tiefe 30)
Das war eine super Lösung für mich. Vielen Dank!
Das ist keine Lösung, sondern ein Workaround. Denn wenn ein Weg mal länger als 30 Einheiten sein sollte, findest du ihn mit dieser Methode nicht mehr.
Das Bild hängt schief.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Stack-Overflow abfangen

  Alt 15. Aug 2011, 07:16
Mal abgesehen davon, dass es extrem viel länger dauert, wenn man sich nicht merkt wo man schon war...
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

AW: Stack-Overflow abfangen

  Alt 15. Aug 2011, 07:47
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.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 01:44 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