链接列表没有正确删除节点

时间:2012-08-29 05:19:39

标签: c list linked-list

我目前正在创建我正在创建的链接列表。基本上发生的事情就是当我在一个函数中释放头节点时它在函数本身中起作用。但是当我尝试从我的main函数访问我的链表时,我访问了最近释放的头,但只释放了其中一个有效负载。

以下是我的代码片段:

struct item  
{
   UINT   time ;          
   UINT   id ;            
   UINT   event ;          
   struct item  *next ;    
};

这是我的节点结构,包含3个不同的有效负载。这是我的初始化。请注意我手动初始化了3个节点进行练习:

struct item *head=NULL, *tail=NULL, *trail=NULL, *end=NULL;    
head=malloc(sizeof(struct item));
trail=head;
trail->next=NULL;

//TEST
{
    head=malloc(sizeof(struct item));
    trail=head;
    trail->next=NULL;

    head->time=50;
    head->event=100;
    head->id=1989;

        //printf("head->time: %d\nhead->event: %d\nhead->id: %d\n",head->time,          head->event, head->id);
        //printf("trail->time: %d\ntrail->event: %d\ntrail->id: %d\n",trail->time,     trail->event, trail->id);

    //this line of code produces a single payload in the linked list
    tail=malloc(sizeof(struct item));
    trail->next=tail;
    tail->time=1;
    tail->event=2;
    tail->id=3;
    trail=tail;
    //up until here
    /*
    tail=malloc(sizeof(struct item));
    trail->next=tail;
    trail=tail;
    // three lines of code needed to create a linked list
    */

    //this is linked to the code above
    tail=malloc(sizeof(struct item));
    trail->next=tail;
    tail->time=5;
    tail->event=7;
    tail->id=60;
    trail=tail;

    trail->next=NULL;
    end=trail;//end of the linked list
        //printf("tail->time: %d\ntail->event: %d\ntail->id: %d\n\n\n",tail->time, tail->event, tail->id);

    //this code prints out the entire linked list
    trail=head;
    do
    {
        TEST printf("trail->time: %d\ntrail->event: %d\ntrail->id:     %d\n\n",trail->time, trail->event, trail->id);      
        trail=trail->next;    
    }
    while(trail!=NULL);
}
//creation of linked list complete
//test to traverse the linked list

忽略我最近刚刚开始在几个小时前做链接列表的评论。现在这是我的问题。当我在函数内部使用free删除链表的头部时,它确实释放了它,但是当我遍历主函数中的链表时,它将输出3个节点。这是我用来在主函数中遍历链表的代码行:

trail=head;
int item=0;
do
{
    item++;
    printf("item %d = %d %d %d\n",item ,trail->time, trail->id, trail->event);
    trail=trail->next;
}
while(trail!=NULL);

这是我用来删除头脑的功能:

void list_head_delete(struct item *head)
{
    struct item *trail;    
    trail=head;
    trail=trail->next;    
    free(head);
    head=trail;
}

遍历我的链表时,通常会输出:

item 1 = 50 1989 100
item 2 = 1 3 2
item 3 = 5 60 7

如果我调用我的函数来删除头部并再次遍历链表,我将得到这个输出:

item 1 = 0 1989 100
item 2 = 1 3 2
item 3 = 5 60 7

1 个答案:

答案 0 :(得分:3)

您的删除功能签名是:void list_head_delete(struct item *head)。使用此签名,您将指针传递给head节点,因此您可以更改指针引用的struct node,但无法更改指针本身。在C中,函数参数是按值传递,因此您传递的实际指针只是一个副本,并且更改为它,例如head=trail;,只会发送到函数中指针的副本。当函数返回时,head将包含它的原始地址,现在引用释放的内存。

如果要更改头指针指向的内容,则需要将指针传递给指针:

void list_head_delete(struct item **head);

使用head参数时,您需要更改删除功能以处理这种额外的引用级别。

或者,您可以将新列表作为函数返回值传回:

struct node *list_head_delete(struct item *head);

// ... and to use it:
head = list_head_delete(head);