当我尝试从电影数据库中删除电影时,我收到segmentation fault
。我无法弄清楚为什么?
我用gdb运行程序,我在这里遇到了分段错误:
(previousNode->next)->previous = previousNode;
有关为什么我在这里遇到问题的任何建议?
答案 0 :(得分:2)
(previousNode-> next) - > previous = previousNode; //分段错误
如果您的列表大小为2并且您要删除第二个节点,那么这将导致错误,因为previousNode->next
将为空,因此(previousNode->next)->previous
将变为(NULL)->previous
这是错误
这样做:
if(previousNode->next!=NULL)
(previousNode->next)->previous = previousNode;
答案 1 :(得分:1)
如果您尝试删除的节点是最后一个节点怎么办?然后currentNode->next
(因此previousNode->next
)将为NULL
,并且您尝试访问导致未定义行为和可能崩溃的NULL
指针。
您可以通过在解除引用之前简单检查previousNode->next
是否为NULL
来解决此问题。
答案 2 :(得分:1)
很可能你有一个空指针,但它也可能是一个坏指针。
由于你正在运行gdb,你可以打印东西。打印一些东西,看看你能弄清楚什么。
从GDB提示:
p previousNode
previousNode
是空指针吗?如果不是:
p previousNode->next
现在怎么样,是一个空指针?
每次将->
运算符应用于空指针时,都会出现seg错误。
要尝试的另一件事:在分配节点的函数中设置断点,并尝试打印节点地址。例如,我刚刚编写了一个名为malloc()
的简单C程序,结果地址为0x17b0010
。如果我打印了一个像previousNode
这样的变量,它就像0x17b01000
那样类似,那看起来似乎有道理;如果它像0xdcdcdcdc
那样不合理。无论该地址是什么,它可能都不是来自我的程序(更可能的是它根本不是一个有效的指针)。
我接下来对Valgrind的推荐。它可以找到您使用malloc()
和free()
可能发生的各种微妙错误。
还有一个想法:您可以在节点结构中添加一个成员,该结构仅用于“健全性检查”。我经常添加一个名为sig
的成员(“签名”的缩写),它在我的每个结构中包含不同的值。然后使用结构的代码可以检查sig
值,如果设置不正确,则必定存在某种错误。例如:
if (!previousNode || !previousNode->next || previousNode->sig != NODE_SIG_VALUE)
{
return ERROR_CODE_BAD_NODE;
}
else
{
(previousNode->next)->previous = previousNode;
return 0; /* SUCCESS */
}
答案 3 :(得分:0)
如果您正在删除一部电影,我想,您正在删除对前一个元素的当前元素的引用,然后将其解除引用(我们需要查看以前的源代码行)。这可以解释为什么previousNode->next
是NULL
。解决此问题的最佳方法是在删除之前解除引用:
node* oldPrevious = NULL;
if(previousNode && previousNode->next)
{
oldPrevious = (previousNode->next)->previous;
(previousNode->next)->previous = previousNode;
}
if(oldPrevious)
free(oldPrevious);