1

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

以下是我的代码片段:

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
4

1 回答 1

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);
于 2012-08-29T05:25:19.760 回答