分段故障删除节点

时间:2013-11-22 06:34:34

标签: c struct gdb nodes

当我尝试从电影数据库中删除电影时,我收到segmentation fault。我无法弄清楚为什么?

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

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

有关为什么我在这里遇到问题的任何建议?

4 个答案:

答案 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->nextNULL。解决此问题的最佳方法是在删除之前解除引用:

node* oldPrevious = NULL;

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

if(oldPrevious)
   free(oldPrevious);