我正在编写一个程序来查找链表中最后一个节点的nth
。该程序产生正确的输出,但是,当我运行该程序时,我在while(fast)
行遇到分段故障。当我使用print语句调试程序时,我注意到即使fast
指针是NULL
(即fast
超出了列表的末尾(,while(fast)
也会被执行。
关于如何修复分割错误,有什么建议吗?
这是我的代码:
#include <vector>
#include <iostream>
using namespace std;
struct Node {
public:
int data;
struct Node* next;
};
void insert(Node*& headPtr, int val) {
Node* temp = new Node;
temp->data = val;
temp->next = headPtr;
headPtr = temp;
}
Node* mth_to_last(Node* head, int m) {
Node* fast = head;
Node* slow = head;
for(int i = 0; i < m; i++) {
fast = fast->next;
}
while(fast) {
fast = fast->next;
slow = slow->next;
}
return slow;
}
int main() {
Node* head;
for(int i = 10; i >= 1; i--) {
insert(head, i);
}
Node* res = mth_to_last(head, 4);
cout << res->data << endl;
}
这是未定义的行为。
使用前未初始化head
节点(实时(:
Node* head = nullptr;
因此,while
循环不会结束,因为head
在开始时包含一些垃圾值。
此外,您也没有初始化第一个节点的next
指针(head
(。现在,它不会造成问题,因为它没有被使用。但是,如果你真的开始使用它,它会引起问题,即更多的UB。因此,您需要在构造函数中初始化它,例如:
struct Node {
Node() : data{0}, next{nullptr} {}
int data;
Node* next;
};
或者,您可以像这样使用默认成员初始化:
struct Node {
int data {0};
Node* next {nullptr};
};
请注意,struct
的默认可见性是public
,因此您不需要提及这一点,除非在同一个struct
中有private
、public
和protected
访问说明符。
此外,在C++中,您可以执行以下操作:
Node* next;
而不是
struct Node* next;
以下是一个具有上述更改的示例:https://godbolt.org/z/uVD76J
相关线程:
- 为什么是"使用命名空间std"被认为是不好的做法