2016-05-06 35 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; 

}