总结报告
感谢所有有用的反馈。 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
。)这里出了什么问题?我不明白为什么同样的逻辑第一次有效,但第二次却不行。
也许是因为我没有为第一个链表释放内存?
最佳答案
此代码存在多个问题。
您忘记将最后一个元素的
next
设置为NULL
。这将导致任何非空列表崩溃。您需要
std::cin.clear()
才能再次读取它。 EOF 标志是“粘性”的。print_list()
函数不处理空列表。对于任何空列表,这都会崩溃。
这些问题中的任何一个都会导致您的程序终止或崩溃,因此您必须修复所有这些问题。请注意一个错误如何使程序因空列表而崩溃,而另一个错误如何导致非空列表崩溃——在这两者之间,程序会因所有列表而崩溃。好吧,如果你幸运的话,至少。如果你运气不好,它可能不会崩溃。
以下是可以自动捕获错误 #1 和 #3 的工具列表:
- GDB(运行
gdb ./a.out
而不是./a.out
,记得用-g
编译)< - Mudflap(用
-fmudflap -lmudflap
编译) - Valgrind(运行
valgrind ./a.out
而不是./a.out
) - Clang 静态分析器
因此,您应该至少使用这四种工具中的一种。我喜欢在同一个项目中使用所有四个。
关于c++ - 为什么这个C++链表程序会终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15354453/