0

我正在尝试在 C 中实现给定链表的 deleteDuplicates。我遇到了 segFault 的问题,我不知道为什么。我的测试用例给它一个带有两个节点的链表,每个节点都有数据 3 如下。在我的 deleteDups 中,您会看到两个被注释掉的 if 块。如果我取消注释,我不会有 segFault 并且代码似乎可以正常工作。

为什么会这样?在我看来,if 语句正是 while 循环检查的内容......

提前致谢!

我的节点结构和代码

typedef struct node{
  int data;
  struct node *next;
} *node;


void deleteDups(node *head)
{
   if (!*head)
        return;
   node current = *head;
   node runner;
   while (current)
   {
        runner = current;
        while (runner->next)
        {
            if (runner->next->data == current->data)
            {
                node tmp = runner->next;
                runner->next = runner->next->next;
                free(tmp);
            }
            /*if(runner->next == NULL)
            {
                break;
            }*/
            runner = runner->next;

        }
        /*if (current->next == NULL)
        {
            break;
        }*/ 
        current = current->next;
    }

}

int main(int argc, char*argv[])
{

node one = (node) malloc (sizeof (struct node));
one->data = 3;
one->next = NULL;

node head = (node) malloc (sizeof (struct node));
head->data = 3;
head->next = one;

printList(head);
deleteDups(&head);
printList(head);

return 0;

}

4

3 回答 3

1

问题在于内部循环条件和分配

runner = runner->next;

由于您只有两个节点,并删除最后一个,因此上述分配将runner等于NULL。然后检查runner->next循环条件。

这在调试器中容易找到,特别是如果您使用它逐行遍历代码以查看发生了什么。我建议你下次试试。

于 2013-11-13T19:23:35.163 回答
1

它出现段错误的原因是:在内部 while 循环的第一次迭代结束时,runner 的值为 null,并且调用操作 ->next 会导致段错误。

逐步详细说明上述情况是如何发生的:

您有两个节点的链表。在下面的内部 while 循环的开始处,

runner points to the first node,       
runner->next points to second node, and    
runner->next->next points to null

在第一次迭代结束时,只有一个节点,因此 runner->next 为 null 。(在第一个注释的 if 语句之后) runner 被分配了 runner->next 的值。所以 runner 的值现在是 NULL。

在下一次迭代开始时,检查 runner->next 会导致 segFault,因为 runner 为 NULL。

-- 此外,为了确保您的函数适用于空列表,您应该检查 if (!head) 而不是 if (!*head)

于 2013-11-13T19:36:00.887 回答
0

问题似乎在于您对 runner->next 的 NULL 检查。当您为列表中的最后一个节点执行这两行时,您的 runner 变为 NULL。

runner->next = runner->next->next;<--- Runner 的 next 在这里是 NULL。

.....

runner = runner->next;<-- Runner 现在为 NULL。

在下一次迭代中,runner->next 崩溃。while 循环条件应该是这样的: while(runner & runner->next)

-多发性硬化症

于 2013-11-13T19:36:43.757 回答