Stack-Overflow

  • Servus,

    hab ein problem mit meinem programm....

    Es geht um eine automatische eintragsprüfung... Sobald das programm 1.111 mal ein ergebniss liefert bekomme ich den fehler:
    "Error: Recursion level has been exceeded - AutoIT will quit to prevent stack overflow."

    Jetz ist die frage wie bekomme ich das weg ohne das gesammte programm umzuschreiben?
    Kann ich das ganze nicht irgendwie "reseten"?

  • Hi,

    wie minx sagte, hast du vermutlich zu viele verschachtelte Funktionsaufrufe. Dadurch erhälst du zu viele verschiedene "Ebenen" und der Stack, der Stapelspeicher, der für die "Verwaltung" dieser Ebenen verantwortlich ist (Push: neue Ebene "oben drauf legen" (davon hast du wohl zu viele!); Pop: "Oberste" Ebene "wegnehmen") läuft über bzw. läuft Gefahr, überzulaufen (dämlicher Satz :pinch: ).

    Das hier führt zu einem solchen Fehler:

    [autoit]


    func1()
    Func func1()
    func1()
    EndFunc

    [/autoit]

    Derselbe Fehler tritt auch bei zu vielen verschachtelten Aufrufen verschiedener Funktionen auf.


    Ohne Skript wird es aber schwierig, dir da wirklich zu helfen.

    Gruß stay

  • das ich in einer funktion eine funktion aufrufe ist auch so gewünscht und mir bewusst.

    Daher ist ja die frage ob ich nicht einfach bei 1.110 datensetzen das ganze reseten kann ohne das programm neuzustarten?

  • Um Rekursionen kontrollieren zu können, muss die Funktion immer eine Abbruchbedingung enthalten. Andernfalls läufst Du immer auf den StackOverflow.
    Also:
    Func1()

    Func Func1()
    If $variable > Wert Then
    Return
    Else
    Func1()
    EndIf

    EndFunc

  • Wenn du nicht gerade Fraktale zeichnest, ist eine Rekursion sinnlos. Es geht garantiert besser. Dazu muss man mal das Skript sehen.


    Beitrag #300

    Einmal editiert, zuletzt von minx (14. Oktober 2012 um 00:49)

  • Wenn du nicht gerade Fraktale zeichnest, ist eine Rekursion sinnlos. Es geht garantiert besser. Dazu muss man mal das Skript sehen.

    Als sinnlos würde ich Rekursionen nicht gerade bezeichnen. Das gibt schön schlanken code um Baumstrukturen durchzukämpfen (Verzeichnisbäume, verschachtelte Strukturen im Active Directory ...).
    Man muss halt wissen wie es funktioniert und worauf man achten muss!

  • Schon. Da aber hier nichts gegeben ist...

    Die Antwort auf die eigentliche Frage fällt recht eindeutig aus: Nein. Du kannst es nicht resetten.

  • Ohne Deinen Code zu sehen können wir leider nicht mehr für Dich tun ...

  • Hi,

    Zitat

    Theoretisch kannst du einen globalen Zähler verwenden, der bei jedem Aufruf der Funktion erhöht wird, und du als Abbruchbedingung eine Grenze dieses Wertes nimmst.

    was die Rekursion völlig ad absurdum führt....nicht die globale Variable ist das Abbruchkriterium, sondern die an die Funktion (und dann darin ausgewertete) übergebene Variable! Ansonsten wäre z.B. eine FOR/TO-Schleife wesentlich Speichersparender.
    Bei der Rekursion werden sämtliche in der Funktion verwendeten Variablen gespeichert, PRO Rekursionsschritt!
    Daher ist es auch nicht vorhersehbar, wann der Speicherüberlauf stattfindet. Kommt immer auch den aktuellen Speicherverbrauch des Inhalts der Funktion an.
    Einzig die maximale Rekursionstiefe ist festgelegt. Lt. Hilfe mit 389 Schritten, aber ich bekommen beim Testen mehr...

    [autoit]

    $a=0
    _test($a)

    [/autoit][autoit][/autoit][autoit]

    func _test($a)
    $a+=1
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $a = ' & $a & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    _test($a)
    endfunc

    [/autoit]
  • Wie schon gesagt wurde, am besten postest du diese Funktion. Möglicherweise hast du einen Fehler eingebaut, der zu einer endlosen Rekursionsschleife und letzten Endes zum Absturz führt. Sollte das nicht der Fall sein bleibt nur ein Umschreiben des codes. Enweder beschränkst du die Rekursion auf eine fixe Ebenenanzahl (siehe oben per Zähler), was dann aber je nach Funktion eben problematisch ist, weil die Operation frühzeitig und somit unvollständig beendet wird, oder aber du überlegst dir wie du das Problem teilweise oder komplett ohne Rekursion lösen kannst.


    Einzig die maximale Rekursionstiefe ist festgelegt. Lt. Hilfe mit 389 Schritten, aber ich bekommen beim Testen mehr...


    Woher stammt diese Zahl? Ich finde unter den Limits lediglich die Zahl 5100, welche sich auf die maximale Rekursionstiefe von call() und execute() bezieht.

    Einmal editiert, zuletzt von misterspeed (14. Oktober 2012 um 11:29)