erste verkettete liste



  • wintik schrieb:

    -Nope, es stürzt nicht ab ^^

    Das wundert mich aber! 😮

    wintik schrieb:

    if (E != NULL) {
    		F->next=E;
    	}
        else F->next=NULL;E=NULL; //also so bin ich mir ganz sicher aber ich rate mal das es nicht so eine saubere lösung ist?
    

    Ne, so meinte ich das nicht. Das E=NULL hat an der Stelle Null Effekt und das Meiste ist komplett überflüssig.
    Worauf ich hinaus will ist, dass du in der main Funktion deine Liste initialisieren solltest:

    struct sEmpList* A = NULL; // Saubere Initialisierung, NULL-Terminierung der Liste gewährleisten.
    

    Nachdem du den Rückgabewert von malloc geprüft hast genügt dann ein einfaches

    F->next=E;
    

    wintik schrieb:

    -also malloc hab ich aus der uni

    Man castet den Rückgabewert von malloc nicht, siehe Link.

    wintik schrieb:

    -aber wird der speicher des zeigers dann nicht einfach wieder frei gegeben?

    Dafür sorgt man mit der Funktion free.
    Aber nicht so:

    wintik schrieb:

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

    So gibst du maximal den Speicher eines Elements frei, nämlich das des zweiten, wenn die Anzahl der Listenelemente >= 2 ist, der Rest der Liste verbleibt im
    Speicher als Speicherleck(memory leak).



  • CJosef schrieb:

    Man castet den Rückgabewert von malloc nicht, siehe Link.

    Wenn man will, dass der Code auch gültiges C++ ist, was ich mal als potentiell durchaus erstrebenswert sehen würde, dann schon... 😉



  • dot schrieb:

    CJosef schrieb:

    Man castet den Rückgabewert von malloc nicht, siehe Link.

    Wenn man will, dass der Code auch gültiges C++ ist, was ich mal als potentiell durchaus erstrebenswert sehen würde, dann schon... 😉

    In dieser Ecke des Forums aber nicht 😃



  • Wie soll ich denn dann ohne den cast vom malloc speicher für das neue element allokieren?

    den listen anfang hab ich in die main geschrieben, spart mir die abfragen und ist wohl auch die beste lösung ^^

    zum wieder freigeben, wie komm ich denn am einfachsten an alle werte? von hinten die liste durchgehen stell ich mir grad zu aufwendig vor aber was anderes fällt mir nicht zu ein 😕



  • wintik schrieb:

    Wie soll ich denn dann ohne den cast vom malloc speicher für das neue element allokieren?

    Cast weglassen, ganz einfach.

    wintik schrieb:

    den listen anfang hab ich in die main geschrieben, spart mir die abfragen und ist wohl auch die beste lösung ^^

    Ja, der Listenanfang ist in diesem Fall in main gut aufgehoben, aber du hast ihn nicht vernünftig initialisiert.

    wintik schrieb:

    zum wieder freigeben, wie komm ich denn am einfachsten an alle werte? von hinten die liste durchgehen stell ich mir grad zu aufwendig vor aber was anderes fällt mir nicht zu ein 😕

    Mit nem Hilfszeiger.



  • wintik schrieb:

    Wie soll ich denn dann ohne den cast vom malloc speicher für das neue element allokieren?

    malloc gibt einen Zeiger auf void zurück.
    Und die sind in alle anderen Datenzeiger konvertierbar.

    wintik schrieb:

    zum wieder freigeben, wie komm ich denn am einfachsten an alle werte?

    Im Prinzip so wie du in auch angefordert hast (evtl in einer anderen Reihenfolge).

    wintik schrieb:

    von hinten die liste durchgehen stell ich mir grad zu aufwendig vor aber was anderes fällt mir nicht zu ein 😕

    Dann ist C wohl nichts für dich.



  • CJosef schrieb:

    wintik schrieb:

    Wie soll ich denn dann ohne den cast vom malloc speicher für das neue element allokieren?

    Cast weglassen, ganz einfach.

    du meinst (char *), wieso ist das denn dann in mehreren quellen so geschrieben? also abgesehen von den gründen die in dem link standen, wenn es überflüssig ist hier ists ja auch quatsch außer man brauchs für C++ oder so

    CJosef schrieb:

    wintik schrieb:

    den listen anfang hab ich in die main geschrieben, spart mir die abfragen und ist wohl auch die beste lösung ^^

    Ja, der Listenanfang ist in diesem Fall in main gut aufgehoben, aber du hast ihn nicht vernünftig initialisiert.

    int main(){ 
        int i=1;
    	char Namen[20];
    
        struct sEmpList* A = NULL; 
    .
    .
    .
    }
    

    ich hab den doch garnicht nochmal hier gepostet?
    was meinst du mit in diesem fall? also wenn ich eine neue liste erstelle und noch keine elemente vorhanden sind ist dies der richtige weg oder gibt es noch weitere ausnahmen?

    CJosef schrieb:

    wintik schrieb:

    zum wieder freigeben, wie komm ich denn am einfachsten an alle werte? von hinten die liste durchgehen stell ich mir grad zu aufwendig vor aber was anderes fällt mir nicht zu ein 😕

    Mit nem Hilfszeiger.

    also wenn ich mir einen hilfszeiger nehme und diesen gleich A setze und dann weiter schiebe hab ich doch wieder das gleiche problem das nach einem free(hilfszeiger) dieser wieder weg ist?

    DirkB schrieb:

    wintik schrieb:

    von hinten die liste durchgehen stell ich mir grad zu aufwendig vor aber was anderes fällt mir nicht zu ein 😕

    Dann ist C wohl nichts für dich.

    das C mir nicht gerade liegt ist mir auch schon aufgefallen, etwas damit klarkommen muss ich trotzdem, deswegen versuch ich soviel es geht zu verstehen und zu lernen 😉



  • wintik schrieb:

    du meinst (char *), wieso ist das denn dann in mehreren quellen so geschrieben?

    Das weiß ich nicht. Vllt. benutzen manche Autoren einen C++ Compiler.
    Ein C++ Compiler kompiliert das nicht ohne den Cast.

    wintik schrieb:

    ich hab den doch garnicht nochmal hier gepostet?

    Oh ... okay!

    wintik schrieb:

    was meinst du mit in diesem fall? also wenn ich eine neue liste erstelle und noch keine elemente vorhanden sind ist dies der richtige weg oder gibt es noch weitere ausnahmen?

    Man hält sich üblicherweise seine Objekte so lange am Leben wie nötig.
    Brauchst man ne Liste irgendwo temporär in einem Programm, dann lagert man die ganze Chose in Funktionen aus und hällt nicht unbedingt alle Objekte während der kompletten Laufzeit des Programms in der main-Funktion.

    wintik schrieb:

    also wenn ich mir einen hilfszeiger nehme und diesen gleich A setze und dann weiter schiebe hab ich doch wieder das gleiche problem das nach einem free(hilfszeiger) dieser wieder weg ist?

    Standard Vorgehen ist vom Ansatz her: next-Zeiger per Hilfszeiger speichern, Vorgänger löschen ... so hangelst du dich durch bis zum Listenende NULL.

    wintik schrieb:

    das C mir nicht gerade liegt ist mir auch schon aufgefallen, etwas damit klarkommen muss ich trotzdem, deswegen versuch ich soviel es geht zu verstehen und zu lernen 😉

    Das am Anfang nicht gleich alles klappt ist normal, gerade bei C. 😃
    Also, nicht entmutigen lassen.



  • dot schrieb:

    CJosef schrieb:

    Man castet den Rückgabewert von malloc nicht, siehe Link.

    Wenn man will, dass der Code auch gültiges C++ ist, was ich mal als potentiell durchaus erstrebenswert sehen würde, dann schon... 😉

    Die Betonung liegt auf wenn.
    😃



  • CJosef schrieb:

    wintik schrieb:

    also wenn ich mir einen hilfszeiger nehme und diesen gleich A setze und dann weiter schiebe hab ich doch wieder das gleiche problem das nach einem free(hilfszeiger) dieser wieder weg ist?

    Standard Vorgehen ist vom Ansatz her: next-Zeiger per Hilfszeiger speichern, Vorgänger löschen ... so hangelst du dich durch bis zum Listenende NULL.

    ah klar, jetzt wo du es geschrieben hast, hätte mir eigentlich auch einfallen können sollen 🙄

    CJosef schrieb:

    wintik schrieb:

    das C mir nicht gerade liegt ist mir auch schon aufgefallen, etwas damit klarkommen muss ich trotzdem, deswegen versuch ich soviel es geht zu verstehen und zu lernen 😉

    Das am Anfang nicht gleich alles klappt ist normal, gerade bei C. 😃
    Also, nicht entmutigen lassen.

    danke danke, besonders für die ermutigung 😃



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

    löschen diese zeilen richtig oder sieht es für mich nur so aus? (also hab noch printList zur kontrolle dahinter,
    das hat aber vorher mit der alten while-schleife auch schon nichts mehr angezeigt)



  • Das sieht vermutlich für dich nur so aus. Wie soll denn B jemals NULL werden?
    Wenn du das anfangs noch nicht überblickst dann mals dir auf, das ist keine Schande und sehr lehr/hilfreich. Mit rumraten kommste nicht allzu weit...



  • sagen wir mal die liste hat 3 elemente

    A->[1|n]->[2|n]->[3|n]->NULL
    

    1.B=A->next;

    A->[1|n]B->[2|n]->[3|n]->NULL
    

    2.free(A);

    [ | ]B->[2|n]->[3|n]->NULL
    

    3.A=B;

    [ | ]B,A->[2|n]->[3|n]->NULL
    

    damit wär man wieder beim ausgangszustand, nur das halt das erste element befreit ist.

    dann müsste im 3ten durchlauf es so aussehen

    1.   B,A->[3|n]->NULL
    2.     A->[3|n]B->NULL
    3.        [ | ]B->NULL
    

    ist dann nicht B=NULL? wer sieht den fehler in meiner logik? ^^


  • Mod

    Bei Zuweisungen steht das Objekt, das verändert werden soll, auf der linken Seite.



  • ach mist, natürlich

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


  • wintik schrieb:

    sagen wir mal die liste hat 3 elemente

    A->[1|n]->[2|n]->[3|n]->NULL
    

    1.B=A->next;

    A->[1|n]B->[2|n]->[3|n]->NULL
    

    2.free(A);

    [ | ]B->[2|n]->[3|n]->NULL
    

    3.A=B;

    [ | ]B,A->[2|n]->[3|n]->NULL
    

    damit wär man wieder beim ausgangszustand, nur das halt das erste element befreit ist.

    dann müsste im 3ten durchlauf es so aussehen

    1.   B,A->[3|n]->NULL
    2.     A->[3|n]B->NULL
    3.        [ | ]B->NULL
    

    ist dann nicht B=NULL? wer sieht den fehler in meiner logik? ^^

    Das sieht gut aus, hättest du das mal auch so umgesetzt 😃

    wintik schrieb:

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

    Das ist noch nicht so prall, das kann noch crashen, wenn A NULL ist!



  • if(A != NULL){
        do { 
            B=A->next; 
            free(A); 
    		A=B;
        }while (B != NULL);
    }
    

    so nicht mehr oder? 🙂


  • Mod

    Stilistisch besser

    while ( A != NULL )
    {
        struct sEmpList* B = A;
        A = A->next;
        free(B);
    }
    

    - A wird nie ungültig
    - die Freigabe erfolgt zum Schluss



  • okay, ist auch einfacher zu lesen


Anmelden zum Antworten