2016-05-06 66 views
-1

我昨天開始C編程,並試圖實現一個鏈表(只是真的很基本)。試圖'免費'在C鏈接列表

到目前爲止,除釋放列表之外,一切工作都很順利。

首先,這裏是我的代碼:

#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; 

} 

我得到以下輸出:

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

嗯,很明顯的 '33' 是我的問題。我真的不知道這怎麼可能是輸出......此外,我不知道爲什麼我的'removeist'不能正常工作。我釋放了我用'malloc'分配的所有內容。我究竟做錯了什麼?

+4

歡迎來到Stack Overflow!這聽起來像你可能需要學習如何使用調試器來遍歷代碼。使用一個好的調試器,您可以逐行執行您的程序,並查看它與您期望的偏離的位置。如果你打算做任何編程,這是一個重要的工具。進一步閱讀:[如何調試小程序](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。 –

+1

請記住,「removelist」清除了整個列表(或其應該)。最重要的是釋放你傳入的指針所指向的內存。所以當你用同一個指針調用'plotlist'時,你正在使用一個懸掛指針! 'if(liste-> headelement!= NULL){'不會保護你免於此。因此,在'removelist'結尾處,只需將'liste-> headelement'設置爲NULL並且不釋放它。儘管如此,你仍然需要釋放它。 –

回答

1

您不檢查plotlist裏面您的列表是否確實存在。您直接嘗試訪問headelement。更好地做到以下幾點:

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"); 
    } 
} 

由於removelist還釋放鏈表結構正因爲如此,你最好將指針設置爲NULL內主。否則,在訪問釋放的內存時會出現未定義的行爲。

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

    return 0; 

}