Thorsten F.: Stack Overflow

Hallo Leute,
bekomme einen Stackoverflow an der Stelle, an der eine Funktion sich selber aufruft.
Woran kann das liegen? Meiner Meinung nach ist der Code total logisch.
Habt ihr da eine Idee, wie ich das in den Griff bekomme?

PS: Die Variablen sind alle global initialisiert.
Gruß,
Thorsten F.

function check_it()
   {
    for(i=random;i<random+one_fields;i++)
    {
     one.push(i);
    }

for(z=0;z<one_fields;z++)
    {
     if(one[z]%8==0)
     {
      debug_one++;
     }
    }

a = one[0];
    b = one[1];
    c = one[2];

if(debug_one>0)
     check_it();
   }

  1. Hi,

    bekomme einen Stackoverflow an der Stelle, an der eine Funktion sich selber aufruft.
    Woran kann das liegen? Meiner Meinung nach ist der Code total logisch.

    ja, und endlos.

    Habt ihr da eine Idee, wie ich das in den Griff bekomme?

    Sorge für eine Abbruchbedingung, die auch dann erfüllt sein kann, wenn sie es beim ersten Mal noch nicht war.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hi,

      äähhmmm. Versteh ich nicht so ganz...

      1. Hi,

        äähhmmm. Versteh ich nicht so ganz...

        was genau verstehst Du denn nicht?

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. Diesen Satz:

          "Sorge für eine Abbruchbedingung, die auch dann erfüllt sein kann, wenn sie es beim ersten Mal noch nicht war."

          Kannst du mir das mal anhand eines Beispiels erläutern?
          Sollst mir ja nicht die Lösung sagen, aber ein einfaches Beispiel würde mich da schon weiterbringen denke ich.

          Gruß,
          Thorsten F.

          1. Hi,

            "Sorge für eine Abbruchbedingung, die auch dann erfüllt sein kann, wenn sie es beim ersten Mal noch nicht war."
            Kannst du mir das mal anhand eines Beispiels erläutern?

            Deine Rekursion wird ausgeführt, sofern die Variable debug_one größer als 0 ist. Du erhöhst den Wert regelmäßig, so dass, nachdem debug_one>0 einmal gegeben ist, es _immer_ gegeben sein wird. Entweder bricht die Funktion also _vor_ dem ersten rekursiven Aufruf ab, oder aber nie.

            Sollst mir ja nicht die Lösung sagen, aber ein einfaches Beispiel würde mich da schon weiterbringen denke ich.

            All the good things must come to an end. Sorge einfach dafür, dass es bei Dir ein Ende gibt.

            Cheatah

            --
            X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
            X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
            X-Will-Answer-Email: No
            X-Please-Search-Archive-First: Absolutely Yes
            1. Hmm..

              irgendwie bekomme ich das hin. Wo ist denn da jetzt noch der Fehler?
              Wenn debug_one = 1 ist, dann ruft die Fkt. sich selber auf und ich setze debug_one dann sofort auf 0. Anscheinend mach ich da noch einen Denkfehler oder?

              function check_it()
                 {
                  random1 = Math.round( Math.random() * (row*col));  //Generiere Zufallszahl zwischen 1und 64
                  for(i=random1;i<random1+one_fields;i++)
                  {
                   one.push(i);          //Packe Zufallszahl und die 2 darauf Folgenden ins Array
                  }

              for(z=0;z<one_fields;z++)        //Untersuche das Array
                  {
                   if(one[z]%8==0 && debug_one==0)      //Wenn eine Zahl vom Array auf rechtem Rand
                   {
                    alert("RANDFELD bei = "+one[z]);
                    debug_one++;
                   }
                  }

              if(debug_one==1)          //s.o., generiere Array erneut
                  {
                   check_it();
                   debug_one--;
                  }
                  else             //wenn alles ok, dann setze Variablen
                  {
                   a = one[0];
                   b = one[1];
                   c = one[2];
                  }
                 }

              1. 你好 Thorsten,

                1. Javascript hat einen sehr begrenzten Stack, wenn es um Rekursion geht. Du
                  kannst also nicht besonders tief verschachtelte Rekursionen machen.

                2. Warum arbeitest du nicht mit lokalen Variablen? Rekursion mit globalen
                  Variablen ist komplizierter als sie sein müsste; eine Änderung eines Wertes
                  hat größere Nebenwirkungen als sonst.

                再见,
                 克里斯蒂安

                --
                Zahnarztbesuch | Toilettenspruch II.
                Keine Schneeflocke faellt je auf die falsche Stelle.
                http://wwwtech.de/
              2. Hallo Thorsten F.,

                if(debug_one==1)          //s.o., generiere Array erneut
                    {
                     check_it();
                     debug_one--;
                    }

                die Zeile "debug_one--;" wird nicht erreicht, da vorher check_it aufgerufen wird. Vertausche mal die Statements. Warum rechnest du, wenn du etwas 0 setzen willst?

                Gruß, Jürgen

                1. Hallo Thorsten F.,

                  if(debug_one==1)          //s.o., generiere Array erneut
                      {
                       check_it();
                       debug_one--;
                      }

                  die Zeile "debug_one--;" wird nicht erreicht, da vorher check_it aufgerufen wird. Vertausche mal die Statements. Warum rechnest du, wenn du etwas 0 setzen willst?

                  Gruß, Jürgen

                  Jo, das wars. Habe mir den Code zigmal angeschaut, aber darauf bin ich nicht gekommen.
                  THX

  2. 1. Frage:

    Ist debug_one korrekt initialisiert worden ?

    Es muß vor dem ersten Aufruf auf Null stehen.
    Und die Variable muß global definiert sein, wenn sie so verwendet wird.

    2. Frage:

    Ist one_fields korrekt initialisiert worden ?
    Es gilt das gleiche wie bei Frage 1

    3. Frage
    Ist random ...

    Grundsätzlich:
    Vermutlich willst du ein paar Parameter global setzen.
    Das ist allerschlechtester Programmierstil, erlaubt nur irgendwelchen notorischen Basic-Programmierern aus den frühen 70er.

    Sobald du eine Funktion mit allen notwenigen Parameter im Call-by-Value hast, melde dich nochmal.

    Gruß,
    Mathias

    1. Habe den ganzen Käse den ich da verzapft habt mal umgeschrieben und es scheint so, als ob das jetzt 1a funktioniert.

      function make_zufall()
         {
          if(klick==0)
          {
           random = Math.round( Math.random() * 64);
           for(i=random;i<random+3;i++)
           {
            zufall.push(i);

      for(a=0;a<3;a++)
            {
             if(zufall[a]%8==0 && c==0)
             {
              for(b=0;b<3;b++)
              {
               zufall.pop();
               c=1;
              }
             }
            }

      if(c==1)
            {
             c=0;
             make_zufall();
            }
           }
          }
          klick++;
         }

      Finde das jetzt auch eigentlich sehr einleuchtend.

      Gruß,
      Thorsten F.

      1. Finde das jetzt auch eigentlich sehr einleuchtend.

        Aber dazu brauchst du keine rekursive Funktion.
        Struppi.

        1. Was ich da brauche weiß ja auch nicht so genau.
          Meine Idee war ja nur, sobald im Array eine Zahl steht, die genau durch 8 teilbar ist, dann mach eben alles nochmal.

          Geht das eventuel noch einfacher?

          Gruß,
          Thorsten F.

          1. Was ich da brauche weiß ja auch nicht so genau.
            Meine Idee war ja nur, sobald im Array eine Zahl steht, die genau durch 8 teilbar ist, dann mach eben alles nochmal.

            Geht das eventuel noch einfacher?

            Ja mit einer while Schleife.

            Struppi.

            1. Formuliere das Problem mal umgangssprachlich.

              Denn wenn es nur darum geht, eine Zufallszahl zu erzeugen, die nicht durch 8 teilbar ist, dann würde ich folgendes machen.

              var r = 0;
              while (r%8 == 0) r = Math.round(Math.random() * 64);
              zufall.push(r);

              Oder noch einfacher:

              zufall.push(Math.round(Math.random() * 8) * 8 + Math.round(Math.random() * 7) + 1);

              das erste random ergibt eine Zahl zwischen 0...7 mit 8 multipliziert,
              der Rest ergibt eine Zahl zwischen 1...7;

              Gruß, Mathias

              1. var r = 0;
                while (r%8 == 0) r = Math.round(Math.random() * 64);
                zufall.push(r);

                Ja, da ist was dran. Ist auch ein bisl weniger Code.
                THX

                Hruß,
                Thorsten F.

                PS: Warum einfach wenns auch kompliziert geht....