Problem mit Verketteterliste



  • Ich habe da auch keinen Fehler gefunden.

    Hier noch die Klassendefinition der Liste

    #ifndef Element
    typedef int Element;
    #endif
    
    class List
    {
    public:
    	List();			//Konstruktor. Erzeugt leere Liste.
    	~List();		//Destruktor.
    
    	int insert (int pos, Element x);
    	//Fuegt x in die Liste an Position pos ein. Elemente danach
    	//werden um 1 Pos. noch rechts verschoben.
    	//Liefert 0, bei falscher Positio (pos < 0 od. pos > lenght); sonst 1.
    
    	int del (int pos);
    	//Loescht Element an Position pos. Element danach
    	//werden um 1 Pos. nach links verschoben.
    	//Liefert 0, bei falscher Position (pos < 0 od. pos >= lenght); sonst 1.
    
    	int get (int pos, Element& x) const;
    	//Liefert Element x an Position pos.
    	//Liefert 0, bei falscher Position (pos < 0 od. pos >= lenght); sonst 1.
    
    	int assign (int pos, Element x);
    	//Weist Element x an Position pos zu.
    	//Liefert 0, bei falscher Position (pos < 0 od. pos >= lenght); sonst 1.
    
    	int lenght() const { return n;}
    	//liefert Anz. Elemente
    
    private:
    	Element* a;	//Liste als dyn. Feld
    	int n;		//Anz. Elemente
    	int gr;		//Feldgröße von a
    };
    


  • Hi!

    Ich befürchte der Fehler liegt nicht in der Definition.

    grüße



  • David_pb schrieb:

    Hi!

    Ich befürchte der Fehler liegt nicht in der Definition.

    grüße

    👍

    wollt ich auch grad schreiben



  • Hi Leute zu eurer kenntnis:

    Beim ersten Aufruf der Funktion "printList (List list)" funktioniert alles.
    Beim zweiten Aufruf der Funtkion gibt es erst den Fehler und zwar das die erste Funktion wohl der erste wert der liste ist nur noch eine Speicheradresse oder so etwas anderes zumindest steht nicht mehr der erste wert zur verfügung.

    MfG
    blind



  • dann wärs ja mal toll, wenn du uns den vollständigen code der liste präsentierst...oder besser doch nicht... 🤡



  • Hi!

    blind schrieb:

    Hi Leute zu eurer kenntnis:

    Beim ersten Aufruf der Funktion "printList (List list)" funktioniert alles.
    Beim zweiten Aufruf der Funtkion gibt es erst den Fehler und zwar das die erste Funktion wohl der erste wert der liste ist nur noch eine Speicheradresse oder so etwas anderes zumindest steht nicht mehr der erste wert zur verfügung.

    MfG
    blind

    Glaubst du wir können hellsehen und uns anhand deiner Klassendefinition die Implementation vorstellen?
    Ich kann das zumindest nicht, daher wäre es sehr nett wenn du deinen Quellcode posten würdest. Ansonsten kann dir schlecht geholfen werden! 🙂

    grüße



  • Ich hab geschrieben, dass hier ein ; fehlt. Wieso wurde das gelöscht? Muss da kein ; hin?

    int lenght() const { return n;}
        //liefert Anz. Elemente
    

    Also so:

    int lenght() const { return n;};
        //liefert Anz. Elemente
    


  • Hi!

    Nein, muss nicht:

    void foo()
    {
      std::cout << "foo\n";
    } // hier ist ja auch kein ";"
    

    grüße



  • Hier für alle die nicht 2 posts zusammen sich angucken können der komplette code des Programms nochmal in einem post

    //main.cpp
    
    #include "listAsArray.h"
    #include "iostream.h"
    
    //Definition von printlist:....
    
    void printList (List list)
    {
    	int n,i;
    	Element wert;
    	int error=2;
    	n=list.lenght();
    	for(i=0;i<n;i++)
    	{
    		error=list.get(i,wert);
    		if(error==0)
    			break;
    		cout<< "Position "<<i<<endl<<"Wert "<<wert<<endl;
    	}
    }
    
    //Hauptprogramm
    
    int main()
    {
    	List list;
    
    	list.insert(0,1);
    	printList(list);
    	cout << endl;
    		// 1|
    
    	list.insert(1,10);
    	printList(list);
    	cout << endl;
    		// 1|10|
    
    	list.insert(1,2);
    	printList(list);
    	cout << endl;
    		// 1|2|10|
    
    	list.assign(1,5);
    	printList(list);
    	cout << endl;
    		//1|5|10|
    
    	list.del(0);
    	printList(list);
    		//5|10|
    	return 0;
    }
    
    //listAsArray.cpp
    
    #include "listAsArray.h"
    
    static const int blockGr =100;	// blockGr wird durch static nach aussen verborgen
    
    List::List()
    {
    	a = new Element[blockGr];
    	gr = blockGr;
    	n=0;
    }
    
    List::~List()
    {
    	delete [] a;
    }
    
    int List::insert(int pos, Element x)
    {
    	if (pos < 0 || pos >n)
    		return 0;		//Falsche Pos.
    	if (n>=gr)			//Kein Platz mehr
    	{
    		Element* h = new Element[gr+blockGr];
    		for ( int j = 0; j<gr;j++)
    			h[j] = a[j];
    		delete[] a;
    		a=h;
    		gr += blockGr;
    	}
    	for (int i = n; i>pos;i--)
    		a[i]=a[i-1];
    	a[pos] = x;
    	n++;
    	return 1;
    }
    
    int List::del(int pos)
    {
    	if(pos<0|| pos >=n)
    		return 0;
    	for (int i=pos;i<n;i++)
    		a[i]=a[i+1];
    	n--;
    	return 1;
    }
    
    int List::get(int pos, Element& x) const
    {
    	if(pos < 0 || pos >= n)
    		return 0;
    	else
    	{
    		x=a[pos];
    		return 1;
    	}
    }
    
    int List::assign(int pos, Element x)
    {
    	if (pos < 0 || pos >=n)
    		return 0;
    	else
    	{
    		a[pos] = x;
    		return 1;
    	}
    }
    
    //listAsArray.h
    
    #ifndef Element
    typedef int Element;
    #endif
    
    class List
    {
    public:
    	List();			//Konstruktor. Erzeugt leere Liste.
    	~List();		//Destruktor.
    
    	int insert (int pos, Element x);
    	//Fuegt x in die Liste an Position pos ein. Elemente danach
    	//werden um 1 Pos. noch rechts verschoben.
    	//Liefert 0, bei falscher Positio (pos < 0 od. pos > lenght); sonst 1.
    
    	int del (int pos);
    	//Loescht Element an Position pos. Element danach
    	//werden um 1 Pos. nach links verschoben.
    	//Liefert 0, bei falscher Position (pos < 0 od. pos >= lenght); sonst 1.
    
    	int get (int pos, Element& x) const;
    	//Liefert Element x an Position pos.
    	//Liefert 0, bei falscher Position (pos < 0 od. pos >= lenght); sonst 1.
    
    	int assign (int pos, Element x);
    	//Weist Element x an Position pos zu.
    	//Liefert 0, bei falscher Position (pos < 0 od. pos >= lenght); sonst 1.
    
    	int lenght() const { return n;};
    	//liefert Anz. Elemente
    
    private:
    	Element* a;	//Liste als dyn. Feld
    	int n;		//Anz. Elemente
    	int gr;		//Feldgröße von a
    };
    


  • Hi!

    Dein Problem ist, das du an printList() keine Referenz übergibst. Also erstellt das Programm eine Kopie von "List" wobei der Zeiger auch kopiert wird, aber es wird kein neuer Speicher reserviert, sondern die Zeigeradresse wird einfach übergeben.

    Am ende von printList() wird die Kopie zerstört, es wird also der Konstruktor aufgerufen und dein Speicher wird gelöscht.
    Jetzt stehst du natürlich beim nächsten insert() ziemlich dumm da, weil dein Speicher weg ist! 😉

    Was du tuen kannst:
    o Einen eigenen Copy Ctor schreiben, der für die Kopie extra Speicher reserviert und die Werte, des zu kopierenden Objekts, ebenfalls kopiert.
    o Einen Referenzenzähler, das Objekt wird erst vollständig zerstört wenn keine Referenz mehr auf es zeigt.
    o Eine Referenz an printList() übergeben.

    grüße

    p.s.: #include "iostream.h" was soll das darstellen?



  • David_pb schrieb:

    #include "iostream.h" was soll das darstellen?

    Die Header wird für die Verwendung von cout benötigt.

    MfG
    Blind

    P.S.: Kannst mir mal ein Beispiel für die richtige Referenzenübergabe geben?



  • blind schrieb:

    David_pb schrieb:

    #include "iostream.h" was soll das darstellen?

    Die Header wird für die Verwendung von cout benötigt.

    Falscher Header - richtig heißt es "include <iostream>" (ohne .h und in spitzen Klammern, da es ein Standard-Header ist)

    P.S.: Kannst mir mal ein Beispiel für die richtige Referenzenübergabe geben?

    void PrintList(const List& list)
    {
      ...
      //der Rest kann so bleiben
    }
    

    (wichtig ist der Parametertyp "const List**&**")



  • Hi!

    Die Klasse sollte übrigens trozdem einen Copy Ctor besitzen. Du hast ja gesehen wie schnell solche Fehler passieren, wenn jemand andres deine Klasse verwendet, der nicht weiß das es Probleme geben kann, der steht dann ebenfalls recht bescheuert da.
    Genauso solltest du deiner Klasse einen Zuweisungsoperator spendieren, da hier das selbe Problem ist.

    grüße


Anmelden zum Antworten