2016-05-06 9 views
-1

'freizugeben' Ich habe gestern C-Programmierung gestartet und versucht, eine verkettete Liste zu implementieren (nur wirklich wirklich grundlegend).Versuch, eine verkettete Liste in C

Bis jetzt funktioniert alles ziemlich gut, außer um eine Liste zu befreien.

Zuerst, hier ist mein Code:

#include <stdio.h> 
#include <stdlib.h> 

/* 
* Struct for elements of the linked list 
*/ 
struct element { 
    struct element* nextelement; 
    int value; 
}; 

/* 
* Struct for a list itself 
*/ 
struct liste { 
    struct element* headelement; 
}; 

/* 
* Function to create new elements 
*/ 
struct element* createelement(int value) { 
    struct element* dummyelement = malloc(sizeof(struct element)); 
    dummyelement->nextelement = NULL; 
    dummyelement->value = value; 
    return dummyelement; 
} 

/* 
* Function to create new (empty) lists 
*/ 
struct liste* createlist() { 
    struct liste* dummylist = malloc(sizeof(struct liste)); 
    dummylist->headelement = NULL; 
    return dummylist; 
} 

/* 
* Add an element to a given list 
*/ 
void addelement(struct liste* liste, int value) { 

    struct element* dummyelement = createelement(value); 
    if (liste->headelement == NULL) { 
     liste->headelement = dummyelement; 
    } else { 
     struct element* iterelement = liste->headelement; 
     while (iterelement->nextelement != NULL) { 
      iterelement = iterelement->nextelement; 
     } 
     iterelement->nextelement = dummyelement; 
    } 

} 

/* 
* Plot the elements of a given list 
*/ 
void plotlist(struct liste* liste) { 
    if (liste->headelement != NULL) { 
     struct element* iterelement = liste->headelement; 
     printf("%d\n", iterelement->value); 
     while (iterelement->nextelement != NULL) { 
      iterelement = iterelement->nextelement; 
      printf("%d\n", iterelement->value); 
     } 
    } else { 
     printf("Where is my head?\n"); 
    } 
} 

/* 
* This should completely remove the list, but it fails... 
*/ 
void removelist(struct liste* liste) { 
    if (liste->headelement != NULL) { 
     struct element* iterelement = liste->headelement; 
     struct element* nextelement = iterelement->nextelement; 
     free(iterelement); 
     while (nextelement != NULL) { 
      iterelement = nextelement; 
      nextelement = iterelement->nextelement; 
      free(iterelement); 
     } 
    } 

    free(liste); 
} 

int main(void) { 

    /* 
    * Creates a new list 
    * Plots the (empty) list 
    * Adds two elements to the list 
    * Plots the list again 
    * Removes the list 
    * Last plot shouldn't really happen, but it does. 
    */ 
    struct liste* mylist = createlist(); 
    printf("First plot.\n"); 
    plotlist(mylist); 
    addelement(mylist, 1); 
    addelement(mylist, 2); 
    printf("Second plot.\n"); 
    plotlist(mylist); 
    removelist(mylist); 
    printf("Third plot.\n"); 
    plotlist(mylist); 

    return 0; 

} 

ich folgende Ausgabe:

First plot. 
Where is my head? 
Second plot. 
1 
2 
Third plot. 
33 

Nun, offensichtlich die '33' ist mein Problem. Ich weiß wirklich nicht, wie das die Ausgabe sein kann ... Außerdem weiß ich nicht, warum mein "Removelist" nicht richtig funktioniert. Ich befreie alles, was ich mit 'malloc' zugewiesen habe. Was mache ich falsch?

+4

Willkommen bei Stack Overflow! Es klingt, als müssten Sie lernen, wie Sie einen Debugger verwenden, um durch Ihren Code zu gehen. Mit einem guten Debugger können Sie Ihr Programm Zeile für Zeile ausführen und sehen, wo es von dem, was Sie erwarten, abweicht. Dies ist ein essentielles Werkzeug, wenn Sie programmieren wollen. Weiterführende Literatur: [Wie kleine Programme zu debuggen] (http://ericlippert.com/2014/03/05/how-to-debug-small-programs/). –

+1

Denken Sie daran, dass 'removelist' die gesamte Liste (oder deren Inhalt) löscht. Am wichtigsten ist die Freigabe des Speichers, auf den der übergebene Zeiger zeigt. Wenn Sie also 'plotlist' mit demselben Zeiger aufrufen, verwenden Sie einen dangling pointer !! 'if (liste-> headelement! = NULL) {' schützt dich davor nicht. Also setze 'liste-> headelement' am Ende von 'removelist' einfach auf NULL und lass es nicht frei. Sie müssen es später jedoch noch frei machen. –

Antwort

1

Sie überprüfen nicht innerhalb plotlist ob Ihre Liste tatsächlich existiert. Sie versuchen direkt, auf die headelement zuzugreifen. Besser wie folgt vorgehen:

void plotlist(struct liste* liste) { 
    if(liste == NULL){ 
     printf("This list does not even exist.\n"); 
    } 
    else if (liste->headelement != NULL) { 
     // ... 
    } else { 
     printf("Where is my head?\n"); 
    } 
} 

Als removelist auch die Listenstruktur als solche befreit, besser Sie den Zeiger auf NULL innerhalb des Haupt gesetzt. Andernfalls erhalten Sie beim Zugriff auf freigegebenen Speicher ein undefiniertes Verhalten.

int main(void) { 
    // ... 
    removelist(mylist); 
    mylist = NULL; 
    printf("Third plot.\n"); 
    plotlist(mylist); 

    return 0; 

} 
Verwandte Themen