Daniel Petratsch: Stack Overflow ??

Hallo!

Ich habe da mal eine kleine Verständnisfrage.

Folgender Java Code verursacht einen Stack Overflow:

---------------------------------->

static int multiply(int a, int b)
  {
  if((a>0)&&(b>0))
    if(a==1)
      return b;
    else
      return multiply(a-1,b)+b;
  else
    return 0;
  }

---------------------------------->

Verstehe aber nicht wieso das so ist, denn diese Funktion kann NIE eine Endlosschleife sein, da ja alle Fälle behandelt werden und in jedem Fall ein return stattfindet, dass die Funktion zum Abbruch bringt. Folgendes könnte ich mir denken: Java ist nicht zufrieden, dass ich den rekursiven Funktionsaufruf in eine "else" Bedingung schreibe, in der im Gegenzug das einzige Element das die Bedingung erfüllen kann auf (a==1) gesetzt ist. Ich denke mal dass der Compiler es deswegen anmeckert, weil er nicht weiss, das ja die zu überprüfende Variable beim rekursiven Aufruf um 1 verringert wird und so denkt, dass sie statisch sei und der Trivialfall niemals eintritt.

Könnte meine Vermutung stimmen? Ansonsten fällt mir leider nichts ein - ist nämlich lästig so ein Stack Overflow Error :)

Danke!

Grüsse,
Daniel

--
Das ist der ganze Jammer, die Dummen sind immer so sicher und die Gescheiten so voller Zweifel.
[Bertrand Russell]
  1. Hi,

    static int multiply(int a, int b)
      {
      if((a>0)&&(b>0))
        if(a==1)
          return b;
        else
          return multiply(a-1,b)+b;
      else
        return 0;
      }

    Ich denke mal dass der Compiler es deswegen anmeckert,

    Also kriegst Du jetzt einen Compilerfehler oder einen Laufzeitfehler (Stack Overflow)?

    Compilierbar müßte es eigentlich sein.
    Mit welchen Werten rufst Du das Teil auf?
    Bei großen Werten für a könnte ich mir durchaus vorstellen, daß das problematisch ist - schließlich wird eine Rekursionstiefe erreicht, die a entspricht (+/- 1, ist mir jetzt zu aufwendig, drüber nachzudenken).

    cu,
    Andreas

    --
    MudGuard? Siehe http://www.Mud-Guard.de/
    1. Hi MudGuard

      Also kriegst Du jetzt einen Compilerfehler oder einen Laufzeitfehler (Stack Overflow)?

      Also ich bekomme einen Laufzeitfehler

      Compilierbar müßte es eigentlich sein.
      Mit welchen Werten rufst Du das Teil auf?
      Bei großen Werten für a könnte ich mir durchaus vorstellen, daß das problematisch ist - schließlich wird eine Rekursionstiefe erreicht, die a entspricht (+/- 1, ist mir jetzt zu aufwendig, drüber nachzudenken).

      Das mit der Rekursionstiefe ist mir schon klar, aber ich rufe die Funktion eigentlich nur mit kleinen Werten auf, zb 5,3  -> es geht mir eigentlich auch mehr ums Prinzip. Sonst könnte ich "alternativ" auch 5*3 schreiben *g*

      Grüsse,
      Daniel

      --
      Das ist der ganze Jammer, die Dummen sind immer so sicher und die Gescheiten so voller Zweifel.
      [Bertrand Russell]
      1. Hi,

        Das mit der Rekursionstiefe ist mir schon klar, aber ich rufe die Funktion eigentlich nur mit kleinen Werten auf, zb 5,3  -> es geht mir eigentlich auch mehr ums Prinzip. Sonst könnte ich "alternativ" auch 5*3 schreiben *g*

        Schon klar. Ich wollt ja vor allem wissen, ob das grundsätzlich auftritt oder nur bei sehr hohen a (irgendwann ist halt einfach der Stack am Überfließen - aber frag mich nicht, wie groß der Stack ist...).

        Hast Du mal

        return b + multiply(a-1,b);

        probiert - also den rekursiven Aufruf am Ende?

        Oder mal {} um das innere if?

        cu,
        Andreas

        --
        MudGuard? Siehe http://www.Mud-Guard.de/
      2. Hallo,

        Also ich bekomme einen Laufzeitfehler

        Das mit der Rekursionstiefe ist mir schon klar, aber ich rufe die Funktion eigentlich nur mit kleinen Werten auf, zb 5,3

        Mit dem Aufrufparametern 5 und 3 tritt definitiv kein StackOverflow
        auf. Es wird korrekt 15 ausgerechnet. Auch mit sehr viel größeren
        Werten tritt kein StackOverflow auf.
        Bist du dir sicher, daß der Laufzeitfehler in der von dir zitierten
        Methode auftritt und daß deine Werte wirklich klein sind?

        Gruß
        Slyh

        1. Hallo Slyh

          Mit dem Aufrufparametern 5 und 3 tritt definitiv kein StackOverflow
          auf. Es wird korrekt 15 ausgerechnet. Auch mit sehr viel größeren
          Werten tritt kein StackOverflow auf.
          Bist du dir sicher, daß der Laufzeitfehler in der von dir zitierten
          Methode auftritt und daß deine Werte wirklich klein sind?

          Ja, es tritt definitiv ein Laufzeit-Stack Overflow ein wenn ich eine Zahl eingebe die grösser als 1 ist(also sobald er mind einmal in die Rekursion eintritt). Es wird das Ergebnis zwar richtig ausgerechnet, aber danach kommt der Overflow...ich verstehs auch nicht, denn die Abbruchbedingung tritt 100%ig ein...

          --
          Das ist der ganze Jammer, die Dummen sind immer so sicher und die Gescheiten so voller Zweifel.
          [Bertrand Russell]
          1. Hallo,

            Ja, es tritt definitiv ein Laufzeit-Stack Overflow ein wenn ich eine Zahl eingebe die grösser als 1 ist(also sobald er mind einmal in die Rekursion eintritt). Es wird das Ergebnis zwar richtig ausgerechnet, aber danach kommt der Overflow...ich verstehs auch nicht, denn die Abbruchbedingung tritt 100%ig ein...

            Wie auch immer. Es liegt nicht an der von dir zitierten Methode.
            Vermutlich hast du später irgendwo einen Fehler drin.

            Gruß
            Slyh

      3. Hab den Fehler gefunden!

        ...Einmal den Computer neugestartet und...naja...dazu kann ich jetzt nicht einmal einen Kommentar abgeben :(  *confused*

        Grüsse,
        Daniel

        --
        Das ist der ganze Jammer, die Dummen sind immer so sicher und die Gescheiten so voller Zweifel.
        [Bertrand Russell]