摘要报告
感谢所有有用的反馈。 cin.clear()
非常好;关于将next
设置为NULL的说法也是如此。但是最终的问题(在评论中被诊断出来)是我使用Ctrl+D
来逃避,cin >> k
没有正确处理这个问题。当我将k > 0
添加到while条件(请参阅更新的代码)并使用负数进行转义时,这一切都开始有效。
我讨厌发布大量代码,但我认为我无法进一步修改它。关键是我的程序首次复飞,但不是第二次。 (跳到main
看看我的意思。)
#include <iostream>
using namespace std;
struct ListNode {
int data;
ListNode* next;
};
void print_list(ListNode* node) {
cout << node->data << endl;
while ((node = node->next) != NULL) {
cout << node->data << endl;
}
}
ListNode* read_list() {
ListNode *head, *tail;
int k;
head = NULL;
while ((cin >> k) && k > 0) {
if (head == NULL) {
head = tail = new ListNode;
} else {
tail->next = new ListNode;
tail = tail->next;
}
tail->data = k;
tail->next = NULL;
}
return head;
}
int main() {
ListNode *list1, *list2;
list1 = read_list();
print_list(list1); // Works
list2 = read_list();
print_list(list2); // Does not work!
return 0;
}
然后是输出:
Press ENTER or type command to continue
1
3
5
7
List1
1
3
5
7
List2
Command terminated
在打印List2
之前,您是否看到它如何终止? (前四行来自stdin。请参阅main
。)这里出了什么问题?我不明白为什么第一次使用相同的逻辑,而不是第二次。
也许是因为我没有释放第一个链表的内存?
答案 0 :(得分:3)
此代码存在多个问题。
您忘记在最后一个元素上将next
设置为NULL
。这将导致任何非空列表崩溃。
在再次阅读之前,您需要std::cin.clear()
。 EOF标志是“粘性的”。
print_list()
函数不处理空列表。任何空列表都会崩溃。
这些问题中的任何一个都会导致程序终止或崩溃,因此您必须修复所有这些问题。请注意一个错误如何使程序在空列表中崩溃,而另一个错误导致非空列表崩溃 - 在这两个错误列表之间,程序崩溃所有列表。好吧,如果你很幸运,至少。如果你不走运,它可能不会崩溃。
这是一个自动捕获错误#1和#3的工具列表:
gdb ./a.out
而不是./a.out
,请记得使用-g
进行编译)-fmudflap -lmudflap
编译)valgrind ./a.out
而不是./a.out
)所以,你应该至少使用这四种工具中的一种。我喜欢在同一个项目中使用所有四个。
答案 1 :(得分:1)
你应该在第一个read_list()之后调用cin.clear()。 The reason can be found here
以下代码效果很好:
#include <iostream>
using namespace std;
struct ListNode {
int data;
ListNode* next;
};
void print_list(ListNode* node) {
cout << node->data << endl;
while ((node = node->next) != NULL) {
cout << node->data << endl;
}
}
ListNode* read_list() {
ListNode *head, *tail;
int k;
head = NULL;
while (cin >> k) {
if (head == NULL) {
head = tail = new ListNode;
} else {
tail->next = new ListNode;
tail = tail->next;
}
tail->data = k;
tail->next = NULL;
}
return head;
}
int main() {
ListNode *list1, *list2;
list1 = read_list();
print_list(list1);
cin.clear(); // ADD this line
list2 = read_list();
print_list(list2);
return 0;
}
问题是由第二个read_list()函数调用中的 cin 引起的。 第一个read_list(),print_list()运行良好。
但是,根据调试器,从 read_list()返回后没有创建 ListNode ,list2是 0x0 ,即 NULL ,导致第二个 print_list()分段错误。
第二个read_list返回NULL的原因是while循环没有运行。声明 cin&gt;&gt;的值k 是 false 。
以上答案错误。如果只是修改read_list函数,问题仍然存在,如下所示。
ListNode* read_list() {
ListNode *head, *tail;
int k;
head = NULL;
while (cin >> k) {
if (head == NULL) {
head = tail = new ListNode;
} else {
tail->next = new ListNode;
tail = tail->next;
}
tail->data = k;
tail->next = NULL;
}
return head;
}
答案 2 :(得分:0)
head = NULL;
while (cin >> k) {
if (head == NULL) {
head = tail = new ListNode;
} else {
我希望你能看到问题所在。首先将头设置为null,然后检查它是否为null。
尝试这样的事情:
ListNode* readList(ListNode* head)
{
int data;
cin >> data;
ListNode* nNode = new ListNode;
nNode->data = data;
nNode->next = 0;
if (head == null)
{
head = nNode;
}
else
{
ListNode* tail = head;
while (tail->next != 0)
{
tail = tail->next;
}
tail->next = nNode;
}
return head;
}
或类似的东西。自从我上次创建链表以来已经有一段时间了。
答案 3 :(得分:0)
修改列表的打印方式:
void print_list(ListNode* node)
{
while (node)
{
cout << node->data << endl;
node = node->next;
}
}
在第二个cin
之前重置read_list
:
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
程序崩溃将解决。