【问题标题】:Showing Segmentation Fault when Attempting to Reverse a Linked List [closed]尝试反转链接列表时显示分段错误[关闭]
【发布时间】:2019-10-17 17:44:03
【问题描述】:

我尝试使用此代码反转单链表的一部分。

这里的startOfSec是链表中要反转的节的起始节点的指针,endofSec是指向该节的最后一个节点的指针。

现在,使用这段代码,我遇到了分段错误,但是如果我将 endOfSec->next 替换为 NULL(我正在更改指针的值,指向该部分的最后一个节点(这将被反转) 的原始链表,也为 NULL) 在 while 循环条件下,它工作得很好!

void reverseList(ListNode* startOfSec, ListNode *endOfSec){

    ListNode *prev = NULL;
    ListNode *curr = startOfSec;
    ListNode *nxt;
    while(curr!=endOfSec->next){
        nxt = curr->next;
        curr->next = prev;
        prev = curr;
        curr = nxt;
    }
}

Callsite:
//code to get start and end pointers
reverseList(start, end);

我希望我的代码在不需要将 end->next 指针设置为 NULL 的情况下反转列表部分。

【问题讨论】:

  • 什么是endOfSec?它指向哪里?您可以尝试创建一个minimal reproducible example 向我们展示吗?
  • @Someprogrammerdude endOfSec 指向我想要反转的列表部分的最后一个节点。例如,如果列表是1->2->3->4->5->6->7->8,而要反转的部分是3->4->5->6,那么 startOfSec 指向 3 而 endOfSec 指向 6

标签: c++ reverse singly-linked-list


【解决方案1】:

这段代码有几个问题,有些问题比其他问题更容易修复。对于这个特定的分段错误,代码演练揭示了原因。让我们看一个简单的例子会发生什么。 (您应该学习如何自己完成此操作,无论是手动还是使用调试器。)

start -> end -> NULL

这是一个包含两个元素的列表,一个名为“start”,另一个名为“end”。嗯,假设“开始”和“结束”也是指向节点的指针。这有点模棱两可,但这次应该不会造成问题。现在反转列表。

reverseList(start, end);

reverseList 中循环的第一次迭代之前(即初始化之后),您的数据如下所示。

startOfSec == start
endOfSec == end;     endOfSec->next == NULL;
prev == NULL
curr == start
nxt == /* uninitialized */

start -> end -> NULL

第一次迭代后,数据已经更新。

startOfSec == start
endOfSec == end;     endOfSec->next == NULL;
prev == start
curr == end
nxt == end

start -> NULL
end -> NULL

第二次迭代后,数据已经更新完毕。

startOfSec == start
endOfSec == end;     endOfSec->next == start;
prev == end
curr == NULL
nxt == NULL

end -> start -> NULL

恭喜,列表已反转。现在我们要做的就是退出循环,所以我们希望curr 等于endOfSec->next。但是,NULL 不等于 start,因此我们继续进行第三次迭代,并在尝试读取 curr->next(又名NULL->next)时崩溃。

总体而言,您需要修改跟踪要反转的部分的开头和结尾的方式。当前崩溃的发生是因为您忘记了该部分的结尾。 (也许改用prev != endOfSec?)如果节的结尾不是列表的结尾,您也会遇到问题(反转节之后的列表部分将丢失在边缘),但这很容易通过更改 prev 的初始化方式来修复。我看到的最大问题是当该部分的 beginning 不是列表的开头时 - 更改单链表需要在更改之前修改节点(也就是 startOfSec 之前的节点) .

【讨论】:

  • 非常感谢您为构建答案所付出的帮助和努力!我意识到问这样的问题很可惜,我应该在调试方面付出更多的努力。下次我会记住这一点的。为了回应您对节前后节点的担忧,我想补充一点,调用站点之前的一部分代码保留了节之前和之后节点的变量(这将被反转)并更改相应地,它们与函数之外的部分的连接。
猜你喜欢
  • 1970-01-01
  • 2021-03-22
  • 2021-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
  • 1970-01-01
  • 2012-10-10
相关资源
最近更新 更多