erste verkettete liste



  • 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.



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

    nach 12938skizzen kommt nie das getauschte raus sondern immer nur 4 elemente wo dann das zweite dann fehlt.

    meine skizze sieht wie folgt aus:

    X=A;
    
    X,A->[1|n]->[2|n]->[3|n]->...
    
    A=A->next;
    
    X->[1|A]->[2|n]->[3|n]->...
    
    X-next=A->next;
      A->next=X;
    
    A->[2|X]->[1|n]->[3|n]->...
    

    sieht jemand meinen fehler? 😕



  • Wertest du den Rückgabewert der Funktion auch aus?
    Steht da ein

    [b]A = [/b]swap(A);
    

    Sonst zeigt das A aus main natürlich weiterhin auf 1.



  • oh gott -.- das es daran scheitert, dann hab ich jetzt die ganze zeit zeiger geschoben und das war garnicht der fehler..



  • Du solltest beim zeichnen auf Papier auch nur die Verlinkungen umzeichnen und nicht die Objekte selber.

    Das folgende stimmt z.B. nicht, da A ja zusätzlich auf das 2. Objekt zeigt

    X->[1|A]->[2|n]->[3|n]->... falsch
    
    X->[1|n]->[2|n]->[3|n]->...
            A-^   so ist besser, 1 und A zeigen auf 2
    

    Am Ende sollte dann

    +----------+
                |          |
      +-->[1|n]-+  [2|n]+  +->[3|n]->...
      | X-^      A-^    |  
      +-----------------+
    

    rauskommen.

    Und da könnetst du dann sehen, warum 2 nicht mehr ausgegeben wird, weil die Information verloren gegeangen ist, wo es liegt.
    Wenn du dann noch unterschiedliche Variablennamen in main und swap hast, ist es sogar klar ersichtlich.



  • Vielen vielen dank leute! ich glaub jetzt hab ichs gerafft

    #include <stdio.h>
    #include <stdlib.h>
    
    struct sEmpList {
    	int PersNr;
    	char *Name;
    	struct sEmpList *next;
    };
    
    struct sEmpList *NewEmployee(struct sEmpList *E, int PersNr,char *Name){
    
    	struct sEmpList *F;
    
    	F= (struct sEmpList*) malloc (sizeof(struct sEmpList));
    	F->PersNr=PersNr;
    	F->Name=Name;
    
    	F->next=E;
    	return(F);	
    }
    
    struct sEmpList *swap(struct sEmpList *A){
    
    	struct sEmpList *X;
    
    	X=A;
    	A=A->next;
    	X->next=A->next;
    	A->next=X;
    
    	return(A);
    
    }
    
    void printList(struct sEmpList *list) {
        while(list != NULL) {
            printf("Personalnummer: %i | ", list->PersNr);
    		printf("Name: %s\n", list->Name);
            list = list->next;
        }
    }
    
    int main(){ 
    
        struct sEmpList *A;
    	A= (struct sEmpList*) malloc (sizeof(struct sEmpList));
    	A->PersNr=1;
    	A->Name="Peter";
    
        A = NewEmployee(A,2,"Hans"); // auf erstes Element achten! ggf. NULL anstatt A
    	A = NewEmployee(A,3,"Wurst"); 
        A = NewEmployee(A,4,"Detlef"); 
        A = NewEmployee(A,5,"Dieter"); 
    	A = swap(A);
    
        printList(A); 
    
    	while (A != NULL) {
    		A=A->next;
    		free(A);
    	}
    
    }
    

    so läuft das programm richtig und gibt auch das aus was gefragt war.
    bin grad am üben für eine prüfung und werd mich noch an weiteren funktionen für verkettete listen erproben, das muss alles sitzen bis nächste woche montag! 🙂



  • Mit deinem Namen wirst du so auf dauer nicht glücklich.

    Gib die Namen doch mal per Hand ein:

    char Namen[30];
    int i = 10;
    
    // statt Zeile 56:
      while(1) {
        scanf("%29[^\n]", Namen);
        if (strlen(Namen) <2)
          break;
        A = NewEmployee(A,i++,Namen); 
      }
    


  • was stimmt denn mit dem namen nicht?


Anmelden zum Antworten