如何将链表中的最后一个节点复制到变量中,然后在C中删除列表中的原始节点?

如何将链表中的最后一个节点复制到变量中,然后在C中删除列表中的原始节点?,c,linked-list,C,Linked List,基本上,我想“接受”最后一个元素。从列表中删除它,但在此之前,它存储在一个变量中,因此它仍然可以作为单独的变量访问,但不再是列表的一部分 编辑 这是一个函数的代码,该函数应将最后一个节点作为变量返回,但将其从列表中删除: struct node * take_last_node() { struct node * back = top; struct node * cursor; while (back->link != NULL) { cu

基本上,我想“接受”最后一个元素。从列表中删除它,但在此之前,它存储在一个变量中,因此它仍然可以作为单独的变量访问,但不再是列表的一部分

编辑

这是一个函数的代码,该函数应将最后一个节点作为变量返回,但将其从列表中删除:

struct node * take_last_node()
{
    struct node * back = top;
    struct node * cursor;
    while (back->link != NULL)
    {
        cursor = back;
        back = back->link;
    }
    cursor->link = NULL; //this is the problem
    return back;
}
其中,游标应该是删除最后一个节点之前的第二个最后一个节点,而back是将从列表中删除并作为变量返回的最后一个节点。如果没有注释行,光标和back将指向正确的节点,但是很明显,back节点不会被删除。所以我添加了这一行,这样后面的节点就可以从列表中删除,但它仍然保存在一个单独的变量中。假设我有一个自上而下的列表:4,3,2,1,NULL。在这个函数中添加了注释行后,最后一个节点确实被删除了,但是游标和back struct变量被上移了,取而代之的是,这个函数返回2,而游标本身指向3,而我希望游标指向2,最后的列表看起来是这样的:4,3,2,NULL,函数返回1

这是完整的代码。它不是真的,但它完美地制造了我目前与真的存在的问题:


请看下面的错误:-

printf("TAKE (%d: %s)\n", retokenise()->data.token.type, retokenise()->data.token.value);
在上面的printf中,您将调用retokenise两次。在第一次调用中,它返回最后一个节点,您正在打印data.token.type的值;在第二次调用中,它返回当前最后一个节点,您正在打印data.token.value。这两个值来自两个不同的节点。在这两个retokenise调用中,都返回两个不同的节点,而不是同一个节点。记住,每次调用都会删除一个节点并返回其地址指针。一个大错误是,您甚至没有释放内存,这将导致内存泄漏

更正如下:-

 struct node *p = retokenise();
 printf("TAKE (%d: %s)\n", p->data.token.type, p->data.token.value);
 free(p);

对于在每次调用中返回不同节点指针的所有函数(例如pop),请更正上述剩余代码,但不要使用无调用函数,因为您没有在此处删除节点。小心点。如果您还需要帮助,请告诉我。

听起来是个好主意。你的代码在哪里?@John Smith将其从列表中删除,但在此之前,它存储在一个变量中-这就是解决方案!1.取消节点与列表的链接,相应地更新所有可能指向它的指针。2.将值从现在孤立的节点复制/移动到某个返回/输出目标。3.删除节点。4.归还从2号船上收获的果实。就这样。@LeednielCrocker这是密码。。抱歉,有点晚了。我的代码和你的代码几乎一模一样,是在我更新的问题的编辑部分写的。问题也写在那里。@JohnSmith,你的代码对我来说很好。它返回列表的最后一个节点,当前的最后一个节点由指针光标指向。光标->链接=NULL;,这里出了什么问题?这句话很好。你目前的问题是什么?问题写在编辑部分。我有一个从上到下的列表:4,3,2,1,NULL。此函数在删除1时返回2,因此最终列表变为4、3、2,NULL,但这并不是我想要的。它确实成功地删除了1,但我还需要的是,在从列表中实际删除1之前,将1保存到一个变量中。所以我想让这个函数做的是让列表像这样:4,3,2,NULL,然后返回1。不是2。@JohnSmith,代码中的上述函数必须仅返回最后一个节点的指针,并且根据您的示例,它必须返回1。我想当你创建这个列表的时候一定有问题。在删除节点之前,只需先打印整个列表,并检查列表是否完美。最好把你所有的密码都放进去。@JohnSmith,请看我的最新答案并更正。您的代码中存在错误,这就是它打印错误值的原因。
 struct node *p = retokenise();
 printf("TAKE (%d: %s)\n", p->data.token.type, p->data.token.value);
 free(p);