free(temp)指针释放链表中的头指针 - 如何保留指向列表原点的指针

时间:2012-03-21 05:34:26

标签: c pointers malloc

我有一个问题,如果我想从链表中删除一个节点,我这样做: 假设:头指向第一个节点。

   deleteFirstNode(struct node * head)
  {
   struct node* temp=head;//this line
   temp->next=head->next->next;
   temp->data=head->next->data;
   free(head);
   head=temp;
  } 

1)这会删除第一个节点吗?

2)如果是这样的话,当我释放头部时,它也不会自由临时指针吗?因为temp和head都指向此行中的相同位置(请参阅代码中“this line”中的注释)。 如果以上两者都是真的,我将如何保留指向列表开头的指针。 ? 非常感谢你。

5 个答案:

答案 0 :(得分:4)

我会传递一个双指针并在这些行上做点什么

deleteFirstNode(struct node ** head) {
  struct node* temp= *head;
  *head = temp->next;
  free(temp);
} 

答案 1 :(得分:1)

是的,你有两个指向同一地址的指针 因此,通过在其中任何一个上调用free()来释放内存将释放指向的内存。

修改
为了理解链接列表,总是在纸上绘制它们。

-------------      ------------       ----------- 
|           |      |          |       |         |
|   head    |----->|  first   |------>| second  | 
|           |      |          |       |         |
-------------      ------------       -----------    

您需要做的步骤是:

隔离first
head指向Second
免费first

temp = head->next; //temp now points to first
head = temp->next; //head now points to second
free(temp);

答案 2 :(得分:1)

  

这会删除第一个节点吗?

  

如果是这样,当我释放头部时,它也不会自由临时指针吗?因为temp和head都指向此行中的相同位置(请参阅   在代码中的“this line”中注释。

是的,它会释放temp指向的内存,因为headtemp都指向同一个内存。执行此方法后,指针head将指向无效的内存位置。

答案 3 :(得分:1)

您要删除head指向的节点;你有几个问题:

1)传入head指针的副本 - 函数无法更改调用函数的原始head指针,因此函数的最后一行{{1真的没什么。当函数返回指向列表中第一个节点的任何内容时,现在将指向释放的内存。实际上,您已经丢失了列表。

2)当您抓取head=temp时,由于head->next->data已被覆盖,您无法获取所需的数据项。

3)head->next也会释放free(head),因为它指向与temp相同的内容。 head有点无意义。

代码中的一些注释:

temp

所以这是deleteFirstNode(struct node * head) { struct node* temp=head; temp->next=head->next->next; // note: this overwrites head->next temp->data=head->next->data; // so this gets what used to be // head->next->next->data free(head); // this frees `temp` (which is an alias for `head`) // - so whats the point of `temp`? head=temp; // this is pointless in more ways than one } 的建议(未经测试)备用版本:

deleteFirstNode()

您必须通过传入指向头指针的指针来调用该函数:

deleteFirstNode(struct node ** head)
{
    struct node* temp = *head;      // temp points to the node we want to free
    struct node* next = temp->next; // next points to what will be the new
                                    //  first node

    free(temp);
    *head=next;
} 

要考虑的另一件事:

  • 如果您的头部指针为struct node* head_pointer; // ... deleteFirstNode(&head_pointer); ,则NULL将无效。你应该让它处理这种情况。

答案 4 :(得分:0)

根据你上面的建议,我的最终代码是删除第一个节点并返回指向头节点的指针(这将是列表中的第二个节点)。

 struct node* freeFirstNode(struct node* head)
{
 struct node* temp;
 temp=head//edited after expert's comment
 temp->next=head->next;//please confirm if this is valid and not Bad pointer.
 temp->data=head->data;
 free(head);//how will I fix this? it will free temp too.
 return(temp);
}