2016-10-03 110 views
0

此代码删除除最后一个节点以外的所有节点。但我希望它删除所有节点。谁能告诉我我做错了什么?无法从链接列表中删除所有节点

deleteall(struct node **start) 
{   
    struct node*temp,*curr;    
    while ((*start)->next!=NULL) 
    {    
     temp=*start;     
     *start=(*start)->next;         
     free(temp);    
     curr=(*start);           
    }   
    if ((*start)->next==NULL) 
    {       
     free(curr);   
    }  
} 
+4

你怎么知道它不会删除最后一个节点? – moooeeeep

回答

2

我创建了链表的基本实现并测试了你的代码。这不是特别漂亮,但它的工作原理:

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

struct node { struct node *next; }; 

struct node* create_node(struct node *next) { 
    struct node* node = malloc(sizeof(struct node)); 
    node->next = next; 
    printf("created %p\n", node); 
    return node; 
} 

void deleteall(struct node **start) 
{   
    struct node*temp,*curr;    
    while ((*start)->next!=NULL) 
    {    
     temp=*start;     
     *start=(*start)->next;         
     free(temp);    
     printf("free'd %p\n", temp); 
     curr=(*start);           
    }   
    if ((*start)->next==NULL) 
    {       
     free(curr);   
     printf("free'd %p\n", curr); 

    }  
} 

int main(int argc, char** argv) { 
    // create root node 
    struct node * ll = create_node(0); 
    // insert three nodes 
    ll->next = create_node(ll->next); 
    ll->next = create_node(ll->next); 
    ll->next = create_node(ll->next); 
    // delete all nodes (including root) 
    deleteall(&ll); 
    return 0; 
} 

输出是:

$ gcc test.c && ./a.out 
created 0xc3c010 
created 0xc3c030 
created 0xc3c050 
created 0xc3c070 
free'd 0xc3c010 
free'd 0xc3c070 
free'd 0xc3c050 
free'd 0xc3c030 

正如你所看到的,所有分配节点实际上free'd。

也许你很困惑的事实,即根节点没有设置为0,但apparantly still contains the remains of the object previously located at that place。如果在释放节点之后将0指定给开始指针,则可以修复该问题:*start = 0;(或者通过取消the other answer中建议的其他curr指针)。


考虑,你可以或者删除列表中的节点递归:

void delete_node_recursively(struct node *node) { 
    if (node) { 
     delete_node_recursively(node->next); 
     free(node) 
    } 
} 

如果你想在年底设定为0根节点,您可以添加一个包装:

void delete_list(struct node **root) { 
    delete_node_recursively(*root); 
    *root = 0; 
} 
0

试试这个:
这是为了简化你的代码。
最后*start变成NULL。 (你的代码不会变成NULL

deleteall(struct node **start){ 
    struct node *temp; 
    while(*start){ 
     temp = *start; 
     *start=(*start)->next; 
     free(temp); 
    } 
}