Löschen einer einfach verketteten Liste im Openbook "C von A bis Z"



  • Hi,

    ich versuche mich in die C-Programmierung einzuarbeiten, da ich bisher nur mit JAVA und PHP gearbeitet habe. Vor allem interessiert mich die Speicherverwaltung und der Umgang mit Zeigern.

    Nun bin ich in dem gennanten Buch an folgender Stelle auf einen Fehler gestoßen oder ich habe etwas falsch verstanden, nur was nun zutrifft, dass weiß ich leider nicht. Ich hoffe, ihr könnt mir weiterhelfen.

    http://www.galileocomputing.de/openbook/c_von_a_bis_z/c_023_000.htm#RxxobKap02300004002BA91F0101E7

    In der Funktion "loesche_alles" ist die Zeile "free(zeiger->next);" aus meiner Sicht falsch, da somit doch auch der Speicher des dritten Elements freigegeben wird, oder ? Der Author sagt zwar "(müsste nicht sein)" zu dieser Zeile aber ich finde sie DARF nicht sein, denn somit wird die while Schleife nach dem ersten Durchlauf beendet, da zeiger und zeiger1 auf NULL zeigen oder nicht ?

    Danke für die Hilfe schon mal im Vorraus und Gruß Roland



  • void loesche_alles(void) {
       struct angestellt *zeiger, *zeiger1;
       /* Ist überhaupt eine Liste zum Löschen vorhanden? */
       if(anfang != NULL) {
          /*Es ist eine vorhanden....*/
          zeiger=anfang->next;
          while(zeiger != NULL) {
             zeiger1=anfang->next->next;
             anfang->next=zeiger1;
             free(zeiger->next);
             free(zeiger);
             zeiger=zeiger1;
          }
          /* Jetzt löschen wir erst den Anfang der Liste */
          free(anfang->next);
          free(anfang);
          anfang=NULL;
          printf("Liste erfolgreich gelöscht!!\n");
       }
       else
          fprintf(stderr,"Keine Liste zum Löschen vorhanden!!\n");
    }
    

    Hmm, du hast recht, der Aufruf 'free(zeiger->next)' ist fehl am Platz (und führt im Ernstfall zu einem double-free). Aber daran können wir auch nichts ändern, also schick die Meldung doch besser an den Autor des Buches.



  • danke für die schnelle Info.

    Bevor ich das als Fehler jemandem weitermelde, wollte ich nur auf Nummer sicher gehen, da ich mich erst seid 14 Tagen mit C beschäftige, hätte es ja auch nen Verständnisproblem meinerseits sein können.

    Nochwas: die Folge ist doch auch, dass somit gar nicht alles gelöscht wird oder ? Die Schleife wird doch nur einmal durchlaufen, da zeiger1 durch den falschen Befehl NULL wird, zeiger auf zeiger1 gebogen wird und dann die Prüfung im Schleifenkopf einen 2. Durchlauf verhindert.

    Gruß Roland



  • Die Zeiger werden durch den free() Aufruf nicht auf NULL gesetzt, nur der dahinterliegende Speicherbereich wird freigegeben (und möglicherweise vom Heap-Manager als unbelegt markiert). Und was dann passiert, ist sogar noch schlimmer als ein Datenverlust - alles, was auf das Element 'zeiger->next' operiert, arbeitet mit undefinierten Daten (inklusive 'anfang' und 'zeiger1'), provoziert also womöglich eine Access Violation.


Anmelden zum Antworten