erste verkettete liste



  • soo, ich versuch mich an verketteten listen, also die theorie versteh ich denk ich wohl, doch irgendwas will nicht klappen,
    er gibt mir nur eine zahl aus irgendeinem speicher aus

    Das ist die ausgabe:
    Personalnummer: 1223461192

    #include <stdio.h>
    #include <stdlib.h>
    
    struct sEmpList {
    	int PersNr;
    	struct sEmplist *next;
    };
    
    struct sEmpList *NewEmployee(struct sEmpList *E, int PersNr){
    
    	struct sEmpList *F;
    
    	F= (struct sEmpList*) malloc (sizeof(struct sEmpList));
    	F->PersNr=PersNr;
    	F->next=E;
    	return(F);	
    }
    
    void printList(struct sEmpList *A) {
        while(A != NULL) {
            printf("Personalnummer: %i\n", A->PersNr);
            A = A->next;
        }
    }
    
    int main(){
    
    	struct sEmpList *A;
    	struct sEmpList *B;
    	struct sEmpList *C;
    	struct sEmpList *D;
    
    	*NewEmployee(A,1);
    	*NewEmployee(B,2);
    	*NewEmployee(C,3);
    	*NewEmployee(D,4);
    
    	printList(A);
    
    }
    


  • In NewEmployee setzt du ein neues Element (F) vor das vorhandene (E), gibst aber die Adresse vom Neuen nicht zurück.

    Du egst 4 verschiedene Listen an.

    A ist bei dir ein Zeiger, der nicht initialisiert ist und auch nicht wird.
    D.h er zeigt auf keinen gültigen Speicher.
    Daraum die falsche Personalnummer.



  • Sorry, du gibst das neue Element zurück.
    Du verwirfst aber den Rückgabewert, da du ihn keiner Variablen zuweist.

    int main(){
    
        struct sEmpList *A;
    
        A = NewEmployee(NULL,1); // erstes Element
        A = NewEmployee(A,2);
        A = NewEmployee(A,3);
        A = NewEmployee(A,4);
    
        printList(A);
    
    // hier fehlt noch die Freigabe. für jedes Element extra
    
    }
    

    (ungetestet)



  • ahh, vielen dank!! schonmal ein weiter schritt nach vorn ^^



  • was meinst du mit Freigabe für jedes einzelne element?

    xcode gibt mir auch noch 2mal diesen fehler aus, weiß jemand damit was an zu fangen?
    F->next=E; assignment from incompatible pointer type



  • was meinst du mit Freigabe für jedes einzelne element?

    Ich denke er meint dass du den Speicher für die verkettete Liste am Ende wieder freigeben musst.

    Zu deinem Fehler, du solltest aus

    struct sEmplist *next;
    

    ein

    struct sEmpList *next;
    

    Keine Ahnung warum, aber der Compiler akzeptiert auch einen unbekannten Typen, hat gedauert bis ich da drauf kam 🙄



  • und ich dachte mir noch, vielleicht lieber alles klein schreiben sonst vergess ich das irgendwo 😃

    okay, kurz noch zur freigabe, ich hab ja erst speicher allocated damit ich genug platz hab für die liste, aber wenn ich diesen am ende wieder freigebe ist die liste ja sogesehen wieder weg, da ich ja den speicher wo sie angelegt ist durch mcih wieder frei ist? oder versteh ich da was falsch?



  • Ja wenn du den Speicher freigibst ist die Liste weg, d.h. auch dass du danach den Zeiger auf sie nicht mehr verwenden kannst.
    Aber du musst halt beachten dass es "die Liste" eigentlich nicht gibt, jedes Listenelement kann an einer anderen Stelle im Speicher stehen kann. Alles was du hast ist ein Startelement und Zeiger auf ein folgendes Element.



  • Der Hinweis zur Freigabe steht auch direkt vor der } von main.
    Da ist das Programm zu Ende. Da ist auch deine Variable A weg und somit jeder Hinweis wo die Liste anfängt.
    Das gibt dann Speicherlecks.



  • okay, meine freigabe sieht so aus

    while (A != NULL) {
    		free(A);
    		A=A->next;
    	}
    

    hab ich das richtig verstanden, am ende der main werden also auch alle variablen wieder feigegeben?



  • wintik schrieb:

    okay, meine freigabe sieht so aus

    while (A != NULL) {
    		free(A);  // ab hier ist der Speicherbereich auf den A zeigt für dich nicht mehr gültig.
    		A=A->next; // hier greifst du aber noch auf A zu.
    	}
    

    hab ich das richtig verstanden, am ende der main werden also auch alle variablen wieder feigegeben?

    Was ist daran so erstaunlich? Das Proramm ist mit verlassen der main zu Ende.

    Alle lokalen (nicht-static) Variablen werden am Ende ihres Scopes freigegeben.

    In deinem Beispiel werden die Variablen E, PersNR und F beim Aufruf von NewEmployee angelegt und beim verlassen der Funktion wieder freigegeben.

    Das betrifft aber nicht den Speicher, den du mit malloc besorgst.



  • Sry, war mir bis jetzt irgendwie noch nicht richtig bewusst, wieder was gelernt 🙂



  • struct sEmpList *swap(struct sEmpList *A){
    
    	struct sEmpList *B,*tmp,*tmp2;
    
    	tmp=A;
    	A=B;
    	B=tmp;
    
    	tmp2=A->next;
    	A->next=B->next;
    	B->next=tmp2;
    
    	return(B);
    
    }
    

    jetzt versuch ich mich an einer swap funktion.
    ich dachte mir am simpelsten wär es einfach je die zeiger auf die "liste" zu
    tauschen sowie deren next-zeiger, doch so tauscht er nichts 😕



  • Wo bekommt B (vor Zeile 6) einen Wert zugewiesen?

    Was willst du überhaupt tauschen?

    Bedenke, dass du nur Zugriff auf nachfolgende Elemente hast.



  • struct sEmpList *swap(struct sEmpList *A){
    
    	struct sEmpList *B,*tmp,*tmp2;
    	B=A->next;
    
    	tmp=A;
    	A=B;
    	B=tmp;
    
    	tmp2=A->next;
    	A->next=B->next;
    	B->next=tmp2;
    
    	return(B);
    
    }
    

    ich will einfach das erste mit dem zweiten element tauschen. B hat jetzt einen
    Wert, doch wenn ich swap benutze gibt er 2 einfach nicht mit aus.. wird also so
    zu sagen gelöscht



  • Du rätselst eunfach rum, ohne dir richtig zu überlegen, was da abgeht.

    Nimm dir mal einen Zettel und mal es dir auf.

    A 
     | 
     |  +------+    +------+    +------+
     +->|PersNr| +->|PersNr| +->|PersNr|
        +------+ |  +------+ |  +------+
        | next |-+  | next |-+  | next |
        +------+    +------+    +------+
    

    Dann zeichnest du ein, wie du die Zeiger verbiegen musst und schreibst es als Programm auf.

    Deine Zeilen 6,7 und 8 sind überflüssig.

    Bedenke aber auch, dass es auch einen Vorgänger von A geben kann.



  • wintik schrieb:

    okay, meine freigabe sieht so aus

    while (A != NULL) {
    		free(A);
    		A=A->next;
    	}
    

    Nach free(A) sollte man A nicht mehr verwenden.



  • slebst mit zeichnung will es nicht wikrlich -.-

    also in worten was ich mir dazu gedacht habe:
    zunächst hab ich damit ich das erste element nicht verlier einen neuen Zeiger X der aufs gleiche zeigt wie A.
    ich biege den zeiger A aufs erste element aufs zweite, dann das next vom ersten element aufs dritte und danach das next vom zweiten element aufs erste.

    doch er gibt mir jetzt nur ne endlosschleife aus

    struct sEmpList *swap(struct sEmpList *A){
    
    	struct sEmpList *X;
    	X=A;
    	A=A->next;
    	A->next=A->next->next;
    	A->next->next=X;
    
    	return(A);
    
    }
    


  • In Zeile 5 lässt du A aufs zweite Element zeigen.
    In Zeile 6 und 7 gehst du aber davon aus, dass A noch auf das erste Element zeigt.

    Nochmal überlegen.



  • wintik schrieb:

    slebst mit zeichnung will es nicht wikrlich -.-

    Wenn du deinen Code nachzeichnest, solltest du auf die Fehler ganz von allein kommen, d.h. wie du deine Liste 'zerhackst' und dadurch einzelne Elemente nicht mehr zugänglich werden...
    Auf jeden Fall solltest du noch Zugriffe(Zuweisungen) auf next-Zeiger, die NULL sein könnten, vermeiden.


Log in to reply