Rekursive Verkettete Listen



  • Hallo!

    Ich habe mich gerade mal daran versucht, eine verkettete Listenverwaltungsfunktion für Schüsse zu machen. Derzeitig arbeite ich an der Anzeigefunktion, das Eintragen funktioniert (hoffentlich) soweit.
    Dafür habe ich folgende Funktionen geschrieben:

    void schussverwalt::Sanz(schuss *anz)
    {
      R->anzrs(G.graphikid, anz->gibx(), anz->giby());//Anzeige des Schuss
      schuss *naechster;//Pointer auf naechsten deklarieren
      if (anz->nach!=NULL)//Wenn der Nachfolger NULL ist, kann was damit angefangen werden
      {
        naechster = anz->nach;//naechster wird erstmal Machfolger
        while ( !naechster->anz() ) //während der naechste net mehr gebraucht wird
        {
          pos--; //ein Schuss weniger vorhanden
          if (naechster->nach!=NULL)//Wenn der Nachfolger vorhanden ist...
          {
            schuss *loscher=naechster;//Dann muessen wir den loeschen, der net mehr gebraucht wird
            naechster = naechster->nach;//dann wird naechster wieder dem Nachfolger zugewiesen
            delete loscher;//und der zwischengespeicherte wird geloescht
          }
          else
          {
            return;//und wenn der Nachfolger NULL ist, wird gleich rausgesprungen -> Kette am Ende
          }
        }
        Sanz(naechster);//Sollten kein Grund zum raussprigen kommen, gehts mit dem naechsten weiter
      }
    }
    
    void schussverwalt::anz()
    {
      if (pos>0) //Wenn ein Schuss vorhanden ist
      {
        Sanz(S);//wird der angezeigt, und diese Funktion zeigt alle Folgeschuesse an
      }
    }
    

    So, das Problem ist, dass diese Funktion seltsamerweise bei dem delete das Programm einfach so aufhält. Wenn ich aber if(loscher) delete loscher; mache, löscht er trotzdem.
    Hat einer von euch eine Ahnung, wieso das nicht funktioniert, oder kann mir einen Hinweis geben, was ich vielleicht ändern müsste?



  • tipp 1:

    schuss *loscher=naechster;//Dann muessen wir den loeschen, der net mehr gebraucht wird
            naechster = naechster->nach;//dann wird naechster wieder dem Nachfolger zugewiesen
            delete loscher;//und der !zwischengespeicherte! wird geloescht
    

    so wie es fuer mich aussieht, wird da gar nichts zwischengespeichert: ein zeiger ist eine adresse. Objekt wird nicht irgendwie kopiert. Wenn du dem delete-operator eine gültige adresse uebergibst, wird das objekt geloescht. Kann das sein, dass das problem hier liegt?

    tipp 2: der code ist unglaublich schwer zu lesen, weil du deutsche bezeichnungen fuer variablennamen und funktionen gewaehlt hast.

    Wenn man sowas "pNext" "pPrevious" und zB "Show" verwendet, dann ist sofort jedem klar worums geht... Aber ob jetzt "anz" für "anzahl" oder "anzeigen" steht und ob "nach" und "naechster" dasselbe bedeutet, das ist fuer mich irgendwie ein raetsel... 😕

    Wenn du schon das alles auf deutsch machst, dann schreib zumindest ganze woerter hin... Das ist der relativ geringe preis dafuer, dass man die konventionen nicht befolgt 🙄 Na gut, sowas kann man niemandem verbieten. Ist auch nur meine subjektive meinung... 🤡

    \edit: was passt dir denn an der STL <list> nicht? bzw. wenn du das alles selbstaendig schreiben willst, warum machst du nicht gleich ne template klasse daraus?



  • Danke für deine Antwort.

    Zu 1.:
    Hm...also es wird ja der Zeiger, der auf ein vorher mit new initiallisiertes Objekt gespeichert, dann der Nachfolger zugewiesen(mit dem dann die Funktion sich selbst wieder aufruft), und dann das Element gelöscht, das normalerweise als nächstes aufgerufen würde...ich seh da keinen Fehler, bzw. versteh net, was daran falsch sein soll.
    Ich meine, ich lösch ja net den Pointer, sondern worauf er zeigt, mit delete loscher;

    Zu 2:
    Na ja, das versteh ich halt besser, und ist ja auch alles kommentiert...aber nächstes mal schreib ichs aus.

    Zum Edit:
    Ich wollte erstmal Funktionsprinzip selbst probieren und so, bis ich das nutze. Und ne Templateklasse mach ich nicht, weil ich nicht weiß wies geht^^
    Das ganze ist ja weniger praktisch, soll mehr so ne Art Übung sein..



  • also, was ich bei der ganzen geschichte überhaupt nicht verstehe, ist die tatsache, dass du eine funktion zum anzeigen haben wolltest, und im code dann plötzlich damit anfängst, irgendwelche objekte zu löschen...

    was willst du denn jetzt? anzeigen oder löschen? das sind ja zwei funktionen, die an sich gar nichts miteinander zu tun haben...

    \edit: gut , template muss es nicht unbedingt sein, aber wenn dein konkreter container ordentlich entworfen und implementiert ist, besteht so eine ausgabe funktion normalerweise aus genau drei zeilen... kann das sein, dass da zu viel code an einem stück zusammenkommt? normalerweise schreibt man sowas in kleineren code-blöcken, sodass man jeden einzeln testen kann, und nicht in so einem riesenroman nach einem fehler suchen muss...



  • Du machst hier einen Fehler:
    Du hast eine konkrete Anwendung für eine verkettete Liste.
    Aber statt Anwendung und Liste zu trennen klatschst du alles zusammen. Dadurch wird dein Code sehr komplex. Verschiedenes solltest du auch getrennt behandeln, denn dann bleibt dein Code übersichtlich und somit fehlerfrei(er).


Anmelden zum Antworten