Doppelt verkettete Liste - ein Element löschen.



  • Hallo,

    ich habe ein kleines Problem mit den doppelt verketteten Listen. Also diese an sich sind eigentlich kein Problem, nur möchte ich ein Element aus der Liste löschen und dabei stürzt das Programm ab.

    Zuerst:
    Ich habe eine Liste aus Objekten der Klasse Bauteil erzeugt. Dabei wurden die Objekte mittels new erzeugt und dann durch 1_Liste.push_back(ptr); eingefügt.
    Nun habe ich die Liste als eine Klasse deklariert, diese heißt Schaltung.

    Nun wollte ich meine einzelnen Elemente mit einer Zahl identifizieren, also ich möchte eine Zahl eingeben z.B. 3 und eine Methode liefert mir das 3. Element der Liste, dass habe ich so gemacht:

    Bauteil* Schaltung::find(int k)
    {
    	Bauteil* actuall = Erstes; 
    	if(k>=1)
    	{
    		if(k>=2)
    		{
    			for(int i=1; i<k; i++)
    			{
    				if( actuall ->ausgang != NULL)
    				{
    					actuall = actuall->ausgang;
    				}
    				else
    				{
    					return NULL;
    				}
    			}
    			return actuall;
    		}
    		else
    		{
    			return actuall;
    		}
    	}
    	else
    	{
    		return NULL;
    	}
    }
    

    Dieser Code funktioniert auch -soweit ich das beurteilen kann -. Nun möchte ich, EIN Element löschen und dann danach meine Liste ausgeben und sehen das da ein Element fehlt. Und ich habe zwei Versionen die sich nur in einer Zeile unterscheiden. Bei der einen habe ich das Objekt was ich nicht mehr anzeigen möchte gelöscht - mittels delete - bei dem anderen habe ich die Liste nur "verschoben"

    void Schaltung::erase(int k)
    {
    	Bauteil* prt = find(k);
    	Bauteil* prt1= prt->getAusgang();
    	Bauteil* prt2= prt->getEingang();
    	if(k==1)
    	{
    		Erstes = prt1;
    		Erstes->setEingang(NULL);
    	}
    
    	if(find(k) == Letztes)
    	{
    		Letztes = prt2;
    		Letztes->setAusgang(NULL);
    	}
    
    	if( k!=1 && (find(k) != Letztes))
    	{
    		prt2->setAusgang(prt1);
    		prt1->setEingang(prt2);
    	}
    	delete find(k);  // Ohne diese Zeile macht er mir eine Ausgabe. 
    }
    

    So, wenn ich dieses Programm ohne delete find(k); laufen lasse, dann hängt sich das Programm nur auf wenn find(k) == Letztes ist, also glaube ich, ich habe 5 Elemente in der Schaltung, wenn ich nun 5 eingebe, dann hängt sich das Programm auf.

    Wenn ich das Programm MIT delete find(k); laufen lasse kommt folgendes:
    Ich gebe an, dass ich das 3. Element löschen möchte und danach soll meine Liste ausgegeben werden.

    void Schaltung::display()
    {
    	Bauteil* actuell = Erstes;
    	if ((this->empty() == 0))
    	{
    		cout << "NULL" << endl;
    		while (actuell != NULL)
    		{
    			actuell->display();
    			actuell = actuell->getAusgang();
    		}
    		cout << "NULL" << endl;
    	}
    	else
    	{
    		cout << "Die Schaltung ist leer" << endl;
    	}
    }
    

    Bild der Ausgabe: http://www.xup.to/dl,83039720/Projekt1_prak06-Problem.png/

    Beschreibung der Ausgabe:
    das 1. Element der Schaltung wird ausgegeben.
    das 2. Element der Schaltung wird ausgegeben.
    3. Element -> Programm hängt sich auf.

    So hier bräuchte ich Hilfe, wieso hängt sich das blöde Programm auf?
    Ich hoffe ich habe alles was ihr braucht geschrieben, falls etwas fehlt fragt einfach :).

    Ich danke jetzt schon mal.

    Liebe Grüße



  • ohhh.

    ich glaube ich habe den Fehler 😉

    Habe jetzt anstatt.

    delete find(k);
    delete ptr;

    gemacht und tada bei der Ausgabe kommt etwas logisches. Trotzallem wäre es schön, wenn jemand drüber schauen könnte um evt. ein paar Fehler auszubessern 🙂

    Danke

    Liebe Grüße


  • Mod

    Saubere Trennung der Zuständigkeiten! Wieso muss sich eine "Schaltung" um Details der Speicherverwaltung kümmern? Oder um die Details, wie eine Liste aufgebaut ist?

    Wenn jedes einzelne Schaltungselement per new erstellt wurde (warum eigentlich? Polymorphie?), dann gehört die Speicherverwaltung auch an diese Stelle. Schönerweise gibt es dafür schon fertige Klassen in der Standardbibliothek, die heißen, je nachdem, was du genau brauchst, unique_ptr oder shared_ptr.

    Wenn die Schaltelemente in Form einer verketteten Liste gespeichert werden (warum eigentlich?), dann gehört die Listenverwaltung auch an diese Stelle. Schönerweise gibt es dafür schon fertige Klassen in der Standardbibliothek, die heißen, je nachdem, was du genau brauchst, list oder forward_list.

    Somit besteht dann die Schaltung aus einer Liste von Schaltelementen, wobei alle Komponenten sich nur um ihre eine Aufgabe kümmern und das dann richtig. Die Schaltung ist dann keine Liste mit Speicherverwaltung mehr, was wohl die wenigsten Leute mit dem Begriff "Schaltung" in Verbindung bringen würden.

    Das gilt - in geringerem Maße - auch für die Ausgabe. Eine Schaltung ist wohl eher nicht etwas, was sich selbst auf eine Standardausgabe schreiben kann (zumindest machen das meine Schaltungen eher selten 🙂 ). Es ist ein Objekt, welches man auf einem Standardausgabestream (oder besser: auf jeder Form von Ausgabestream) ausgeben kann.

    P.S.: Ich bin ja eigentlich kein Freund von Rechtschreibflames, aber bei "actuall" geht einfach zu vieles schief (Rechtschreibung, Wortwahl, Sprache). Da muss ich dich einfach drauf aufmerksam machen, bevor du es jemand anderem zeigst.


Anmelden zum Antworten