使链表的节点到最后一个节点的功能?

时间:2011-07-30 18:42:18

标签: c linked-list

此函数将获取链表的特定节点并使其成为最后一个节点。

void lastNode(struct list *node)
{
  struct list* temp = node->next;
  node->next = NULL;
  struct list* temp2;
  while(temp)
    {

      temp2 = temp->next;
      printf("%p \n",temp);
      free(temp);
      temp = temp2;
    }

}

int main()
{
  struct list d={4,NULL};
  struct list c={3,&d};
  struct list b={2,&c};
  struct list a={1,&b};


  struct list *node = &a;

  lastNode(&b);

  while(node)
    {
      printf("%d \n",node->d);
      node=node->next;
    }
  return 0;
}

但它在释放节点方面给我错误。

2 个答案:

答案 0 :(得分:1)

更新:这是在提供免费功能的来电之前写的。现在我看到了,我会说是的,你不能在堆栈地址上调用free。但是我的原始答案保留在下面,关于如何更好地删除列表......


我没有看到突然出现free错误,但......看起来这种方法只有在传入的node是第一个节点时才有效。如果它是除第一个节点以外的某个节点,则需要指向前一个节点,因此您可以设置prev->next = node->next

实际上,更多地考虑这个...如果你所做的只是拿一个节点并将其作为最后一个节点,为什么你需要free什么呢?看起来这段代码从temp开始释放整个列表。如果这是你的意图我推荐更像这样的东西:

void free_all_at_node(struct list **list, struct list *node_to_free)
{
   struct list *n = *list, *prev = NULL;

   // Search for node_to_free, updating prev to indicate the last node we saw.
   //
   while (n && n != node_to_free)
   {
      prev = n;
      n = n->next;
   }

   // Check to see if we found it...
   //
   if (n == node_to_free)
   {
      // Do we have a previous node?
      //
      if (prev)
      {
         // Yes, update next pointer...
         //
         prev->next = NULL;
      }
      else
      {
         // This is the start of the list.  Update the head...
         //
         *list = NULL;
      }

      // Now free stuff...
      //
      while (n)
      {
         struct list *next = n->next;
         free(n);
         n = next;
      }
   }
}

假设您希望node_to_free成为第一个释放的节点,因此我们会在列表的开头搜索它。另一种方法是让调用者在第一个节点之前指定节点。 (看起来你的代码实际上是在尝试这样做......)我可能更喜欢这样做:

void free_after_node(struct list *n)
{
   // If the node is NULL or has no next node, there is nothing to do.
   //
   if (n && n->next)
   {
      // Start at the node after the first, since we want to keep the first
      // one around.
      //
      n = n->next;

      // Now free...
      //
      while (n)
      {
         struct list *next = n->next;
         free(n);
         n = next;
      }
   }
}

答案 1 :(得分:1)

查看完整代码:

struct list c={3,&d};
struct list b={2,&c};

lastNode(&b);

free temp不合法,因为它未使用malloc分配。

struct list* temp = node->next; /* temp is now &c. You can't free it. */
while(temp)
{
    /* ... */  
    free(temp); /* Tries to free &c which is on the stack. */
}