c++ - 为什么这个C++链表程序会终止?

标签 c++ linked-list

总结报告

感谢所有有用的反馈。 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。)这里出了什么问题?我不明白为什么同样的逻辑第一次有效,但第二次却不行。

也许是因为我没有为第一个链表释放内存?

最佳答案

此代码存在多个问题。

  1. 您忘记将最后一个元素的 next 设置为 NULL。这将导致任何非空列表崩溃。

  2. 您需要 std::cin.clear() 才能再次读取它。 EOF 标志是“粘性”的。

  3. 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/

相关文章:

java - 使用带有链表的冒泡排序

java - 如何在java中查找通用单链表的大小

java - 获取 Java 的列表迭代器以返回 Object 以外的内容

java - 你如何在不给别人源代码的情况下共享 Java 函数?

c++ - C++ 是否允许在可变参数模板参数之后使用普通参数?

C++ - 方法和重载中的 const 关键字

java - 需要解释 OpenCV Android 行为

c++ - 我们可以给静态数组的大小一个变量吗

c - 为什么这个链表会出现段错误?

使用一个函数创建两个链表