我在不同版本的 GNU 的不同机器上测试了这个代码片段,只有一台带有 Clang 1001.0.46.3 的奇怪 Mac 报告段错误。这段代码是否有地址问题或指针问题?
#include <iostream>
#include <vector>
using namespace std;
class Node
{
public:
Node* next;
int val;
};
class List
{
private:
Node* head;
Node* tail;
public:
List()
{
head = tail = nullptr;
}
bool isEmpty()
{
if(!head && !tail) return true;
return false;
}
void pushBack(int num)
{
Node* newNode = new Node;
newNode->val = num;
if(isEmpty()) head = tail = newNode;
else
{
tail->next = newNode;
tail = tail->next;
}
}
void pushFront(int num)
{
Node* newNode = new Node;
newNode->val = num;
if(isEmpty()) head = tail = newNode;
else
{
Node* tmp = head;
newNode->next = tmp;
head = newNode;
}
}
void popBack()
{
if(head == tail) {delete head; head = nullptr; return;}
Node* tmp = head;
while(tmp->next != tail) tmp = tmp->next;
tail = tmp;
delete tmp->next;
tmp->next = nullptr;
}
void popFront()
{
if(head == tail) {delete head; head = nullptr; return;}
Node* tmp = head;
tmp = tmp->next;
delete head;
head = nullptr;
head = tmp;
}
int findLen()
{
if(isEmpty()) return 0;
int len = 0 ;
Node* tmp = head;
while(tmp)
{
len++;
//if(tmp == tail) break;
tmp = tmp->next;
}
return len;
}
void inserter(int position, int num)
{
if(position > findLen() || isEmpty()) return;
int index = 0;
Node* tmp = head;
Node* newNode = new Node;
newNode->val = num;
if(position == 0) {pushFront(num); return;}
else if(position == findLen()) {pushBack(num); return;}
while(tmp->next)
{
index++;
if(index == position)
{
Node* tmp2 = tmp->next;
tmp->next = newNode;
newNode->next = tmp2;
return;
}
tmp = tmp->next;
}
}
void print()
{
if(isEmpty()) return;
cout << "list = ";
Node* tmp = head;
while(tmp)
{
cout << tmp->val << " ";
if(tmp == tail) break;
tmp = tmp->next;
}
cout << endl;
}
};
int main()
{
cout << "delete added" << endl;
List testList;
testList.pushBack(5);
testList.pushBack(10);
testList.pushBack(15);
testList.pushBack(20); // after this line, we got segmentation fault
cout << "len = " << testList.findLen() << endl;
testList.print();
testList.pushFront(5);
testList.pushFront(10);
testList.pushFront(15);
testList.pushFront(20);
cout << "len = " << testList.findLen() << endl;
testList.print();
testList.inserter(0,8);
cout << "len = " << testList.findLen() << endl;
testList.print();
testList.inserter(9,555);
cout << "len = " << testList.findLen() << endl;
testList.print();
testList.inserter(5,333);
cout << "len = " << testList.findLen() << endl;
testList.print();
cout << "popBack" << endl;
testList.popBack();
cout << "len = " << testList.findLen() << endl;
testList.print();
cout << "popFront" << endl;
testList.popFront();
cout << "len = " << testList.findLen() << endl;
testList.print();
cout << "popBack" << endl;
testList.popBack();
cout << "len = " << testList.findLen() << endl;
testList.print();
cout << "popFront" << endl;
testList.popFront();
cout << "len = " << testList.findLen() << endl;
testList.print();
return 0;
}
跟进:嘿,伙计们,我刚刚自己得到了一些线索。我认为问题应该出在操作系统方面。检查相关的汇编代码后,我注意到即使局部变量的默认初始化值为 0,但它们并不总是零。我认为问题应该是操作系统的分页方案。我将尽力弄清楚 MacOS(内核 10.15.1)和 linux 如何选择页面以及如何为局部变量生成随机值。如果有人知道这个领域或有任何线索可以弄清楚,请随时告诉我。干杯。
最佳答案
您的问题是在每个 Node
中,next
成员未初始化。
取消注释行
//if(tmp == tail) 中断;
在方法 findLen
中也是一个解决方案。
解决此问题的正确方法是将您的 Node 类重写为
class Node
{
public:
Node* next = nullptr;
int val;
};
无论如何,我希望这只是家庭作业或练习,否则请使用旧的std::list
。
关于c++ - 奇怪的 C++ 链表错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58834292/