我刚刚开始学习链接列表,我正在练习写一些基本功能,如添加或删除。该程序工作了一段时间,但后来我想我做了一些事情,它开始给我分段错误在我的删除功能就是这样。分段错误在if中的while循环中。知道为什么吗?提前谢谢,抱歉我的英语不好:)。
void deleteNode(struct node **first, int age)
{
struct node *tempNode;
if((*(*first)).age == age)
{
tempNode = *first;
*first = (*first)->next;
free(tempNode);
}
struct node *currentNode = (*first)->next;
struct node *lastNode = *first;
while(currentNode!=NULL)
{
//Segmentation Fault
if(currentNode->age == age)
{
tempNode = currentNode;
lastNode->next = currentNode->next;
free(tempNode);
}
lastNode = currentNode;
currentNode = currentNode->next;
}
}
答案 0 :(得分:1)
此处的问题是您在释放后引用lastNode
。如果我们查看循环的跟踪,您可以释放已分配给tempNode
的{{1}},然后将currentNode
设置为lastNode
。您希望currentNode
指向最后一个有效节点,因此更新lastNode
仅在未释放lastNode = currentNode
时才有效。
简而言之,如果您不删除当前节点,则修复仅指定currentNode
。
答案 1 :(得分:0)
如果lastnode为null怎么办?我认为在你正在运行的例子中,lastnode在while循环中为空。
答案 2 :(得分:0)
从列表中释放节点的技巧是在释放节点之前从节点中获取信息。尝试访问已释放的内存会导致未定义的行为。
在这种情况下,您只处理next
,并且您正在跟踪lastNode
。因此,lastNode->next
是逻辑currentNode
。
在您的函数开头,您考虑了first
节点与age
匹配的情况。但是,如果是这种情况,则下一个节点也可能匹配age
。因此,您的first
匹配age
案例也需要成为循环。
使用上一个节点的下一个地址的概念来代表{{1}},而不是编写两个循环。这很有效,因为lastNode
已经是指向first
的指针。
node