C 分段故障删除节点

C 分段故障删除节点,c,struct,gdb,nodes,C,Struct,Gdb,Nodes,当我试图从我的电影数据库中删除一部电影时,我遇到了一个分割错误。我不明白为什么 我用gdb运行了这个程序,我在这里遇到了一个分段错误: (previousNode->next)->previous = previousNode; 关于我在这里遇到问题的原因,有什么建议吗?如果您尝试删除的节点是最后一个,该怎么办?然后currentNode->next(因此previousNode->next)将为NULL,您尝试访问NULL指针,导致未定义的行为和可能的崩溃 在取消引用之前,只

当我试图从我的电影数据库中删除一部电影时,我遇到了一个
分割错误。我不明白为什么

我用gdb运行了这个程序,我在这里遇到了一个分段错误:

 (previousNode->next)->previous = previousNode; 

关于我在这里遇到问题的原因,有什么建议吗?

如果您尝试删除的节点是最后一个,该怎么办?然后
currentNode->next
(因此
previousNode->next
)将为
NULL
,您尝试访问
NULL
指针,导致未定义的行为和可能的崩溃


在取消引用之前,只需检查
previousNode->next
是否为
NULL
,即可解决此问题。

如果尝试删除的节点是最后一个,该怎么办?然后
currentNode->next
(因此
previousNode->next
)将为
NULL
,您尝试访问
NULL
指针,导致未定义的行为和可能的崩溃


在取消引用之前,只需检查
previousNode->next
是否为
NULL
即可解决此问题。

很可能是空指针,但也可能是坏指针

因为您运行的是gdb,所以可以打印东西。打印一些东西,看看你能找到什么

从GDB提示符:

p previousNode
previousNode
是空指针吗?如果没有:

p previousNode->next
现在,这是一个空指针吗

任何时候将
->
运算符应用于空指针时,都会出现seg故障错误

另一件要尝试的事情是:在分配节点的函数中设置断点,然后尝试打印节点地址。例如,我刚刚编写了一个名为
malloc()
的普通C程序,结果地址是
0x17b0010
。如果我打印了一个类似于
previousNode
的变量,它类似于
0x17b01000
,那么这看起来似乎是合理的;如果它是类似于
0xdcdc
的东西,那就不可信了。不管那个地址是什么,它可能不是来自我的程序(更可能的是它根本不是一个有效的指针)

我支持Valgrind的建议。它可以发现你在使用
malloc()
free()
时可能犯的各种细微错误

还有一个想法:您可以将一个成员添加到节点结构中,该成员仅用于“健全性检查”。我经常添加一个名为
sig
(signature的缩写)的成员,它在我的每个结构中都包含不同的值。然后,与结构一起工作的代码可以检查
sig
值,如果设置不正确,则一定存在某种错误。例如:

if (!previousNode || !previousNode->next || previousNode->sig != NODE_SIG_VALUE)
{
    return ERROR_CODE_BAD_NODE;
}
else
{
    (previousNode->next)->previous = previousNode;
    return 0; /* SUCCESS */
}

很可能是空指针,但也可能是坏指针

因为您运行的是gdb,所以可以打印东西。打印一些东西,看看你能找到什么

从GDB提示符:

p previousNode
previousNode
是空指针吗?如果没有:

p previousNode->next
现在,这是一个空指针吗

任何时候将
->
运算符应用于空指针时,都会出现seg故障错误

另一件要尝试的事情是:在分配节点的函数中设置断点,然后尝试打印节点地址。例如,我刚刚编写了一个名为
malloc()
的普通C程序,结果地址是
0x17b0010
。如果我打印了一个类似于
previousNode
的变量,它类似于
0x17b01000
,那么这看起来似乎是合理的;如果它是类似于
0xdcdc
的东西,那就不可信了。不管那个地址是什么,它可能不是来自我的程序(更可能的是它根本不是一个有效的指针)

我支持Valgrind的建议。它可以发现你在使用
malloc()
free()
时可能犯的各种细微错误

还有一个想法:您可以将一个成员添加到节点结构中,该成员仅用于“健全性检查”。我经常添加一个名为
sig
(signature的缩写)的成员,它在我的每个结构中都包含不同的值。然后,与结构一起工作的代码可以检查
sig
值,如果设置不正确,则一定存在某种错误。例如:

if (!previousNode || !previousNode->next || previousNode->sig != NODE_SIG_VALUE)
{
    return ERROR_CODE_BAD_NODE;
}
else
{
    (previousNode->next)->previous = previousNode;
    return 0; /* SUCCESS */
}
(previousNode->next)->previousNode=previousNode;//分段故障

如果您的列表大小为2,并且您正在删除第2个节点,那么这将导致错误,因为您的
previousNode->next
将为Null,因此
(previousNode->next)->previous
将变为
(Null)->previous
,这是错误的

这样做:

if(previousNode->next!=NULL)
  (previousNode->next)->previous = previousNode;
(previousNode->next)->previousNode=previousNode;//分段故障

如果您的列表大小为2,并且您正在删除第2个节点,那么这将导致错误,因为您的
previousNode->next
将为Null,因此
(previousNode->next)->previous
将变为
(Null)->previous
,这是错误的

这样做:

if(previousNode->next!=NULL)
  (previousNode->next)->previous = previousNode;

如果您要删除一部电影,我想,您要从上一个元素中删除对当前元素的引用,然后取消对它的引用(我们需要查看以前的源代码行才能确定)。这将解释为什么
previousNode->next
NULL
。解决此问题的最佳方法是在删除前取消引用,即:

node* oldPrevious = NULL;

if(previousNode && previousNode->next)
{
   oldPrevious = (previousNode->next)->previous;
   (previousNode->next)->previous = previousNode;
}

if(oldPrevious)
   free(oldPrevious);

如果您要删除一部电影,我想,您要从上一个元素中删除对当前元素的引用,然后取消对它的引用(我们需要查看以前的源代码行才能确定)。这将解释为什么
previousNode->next
NULL
。解决此问题的最佳方法是在删除前取消引用,即:

node* oldPrevious = NULL;

if(previousNode && previousNode->next)
{
   oldPrevious = (previousNode->next)->previous;
   (previousNode->next)->previous = previousNode;
}

if(oldPrevious)
   free(oldPrevious);

非常感谢您使用
gdb
。但您应该更广泛地使用它(例如,使用其
回溯
显示
打印
监视
等…命令)。也使用;也许
previousNode->next
NULL
。。。(使用
打印
检查
gdb
内部)您确定要
免费(标题)?如果打电话的人进来了怎么办