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
内部)您确定要免费(标题)代码>?如果打电话的人进来了怎么办