C++实现链表时报segmentation fault (core dumped)如何修复
问题现象
C++初学者编写支持控制台输入数值、输出完整链表结构的程序时,输入第一个数值后程序直接崩溃,报错signal: segmentation fault (core dumped),不清楚错误成因与修复方案,原代码如下:
#include <iostream> using namespace std; class Node{ public: int value; Node *next; public: Node(int value, Node *next = nullptr) { this->value = value; this->next = next; } int getValue() {return this->value;} Node *getNext() {return this->next;} void setNext(Node*next) {this->next = next;} }; class LinkedList { private: Node *head; public: LinkedList() { this->head = nullptr; } ~LinkedList() { while(this->head != nullptr) pop(); } friend std::ostream & operator <<(std::ostream &os, const LinkedList &rhs) { for(Node *curNode = rhs.head; curNode != nullptr; curNode = curNode->getNext()) { os << curNode->getValue(); if (curNode->getNext() != nullptr) os << ""; } return os; } void push(int value) { this->head = new Node(value, this->head); } int pop() { int value; if (this->head != nullptr) { value = this->head->getValue(); Node *temp = this->head; this->head = this->head->getNext(); delete temp; } else { throw std::range_error("List is empty!"); } return value; } }; void append(Node** head_ref, int new_data) { Node* new_node = new Node((*head_ref)-> value); Node *last = *head_ref; new_node->value = new_data; new_node->next = NULL; if (*head_ref == NULL) { *head_ref = new_node; return; } while (last->next != NULL) { last = last->next; } last->next = new_node; return; } void printList(Node* n) { while (n != NULL) { std::cout << n->value << " "; n = n->next; } } int main() { Node* head = NULL; int a; cout << "Please enter value 1#: "; cin >> a; append(&head, a); int b; cout << "Please enter value 2#: "; cin >> b; append(&head, b); int c; cout << "Please enter value 3#: "; cin >> c; append(&head, c); int d; cout << "Please enter value 4#: "; cin >> d; append(&head, d); int e; cout<<"Created Linked list is: "; printList(head); return 0; }
错误原因
- 核心触发点是空指针解引用:第一次调用
append时,传入的头指针head初始值为NULL(空指针,不指向任何有效内存),但函数第一行就执行new Node((*head_ref)-> value),直接读取空指针指向内存的value成员,访问了操作系统禁止访问的内存地址,直接触发段错误。 - 代码逻辑混杂:代码中已经实现了封装完整的
LinkedList类,但main函数、append、printList函数完全没有使用该类,反而编写了一套独立的C风格链表操作逻辑,两套逻辑混杂提升了出错概率。 - 节点初始化逻辑冗余:创建新节点时传入的参数是头节点的值,后续又手动覆盖
new_node的value和next成员,完全违背了Node构造函数的设计意图,属于无效代码。 - 存在无用变量:
main函数中定义了int e但全程未使用,属于冗余代码。 - 输出逻辑缺陷:重载的
<<运算符中节点之间没有输出分隔符,最终打印的所有数值会连在一起,可读性差。
修复方案
- 调整
append函数的执行顺序:将空指针判断逻辑移到指针解引用操作之前,禁止在确认指针有效前访问其指向的内存。 - 修正新节点创建逻辑:直接调用
Node构造函数传入新数值和空指针初始化节点,不需要后续手动给节点成员赋值。 - 删除无用冗余代码,包括未使用的变量
e、无效的节点成员手动赋值逻辑,补全输出分隔符。 - 补充链表内存释放逻辑,避免程序运行出现内存泄漏。
修复后的完整可运行代码如下:
#include <iostream> #include <stdexcept> using namespace std; class Node{ public: int value; Node *next; public: Node(int value, Node *next = nullptr) { this->value = value; this->next = next; } int getValue() {return this->value;} Node *getNext() {return this->next;} void setNext(Node*next) {this->next = next;} }; class LinkedList { private: Node *head; public: LinkedList() { this->head = nullptr; } ~LinkedList() { while(this->head != nullptr) pop(); } friend std::ostream & operator <<(std::ostream &os, const LinkedList &rhs) { for(Node *curNode = rhs.head; curNode != nullptr; curNode = curNode->getNext()) { os << curNode->getValue(); if (curNode->getNext() != nullptr) os << " "; } return os; } void push(int value) { this->head = new Node(value, this->head); } void append(int value) { Node* new_node = new Node(value); if (this->head == nullptr) { this->head = new_node; return; } Node* last = this->head; while (last->next != nullptr) { last = last->next; } last->next = new_node; } int pop() { int value; if (this->head != nullptr) { value = this->head->getValue(); Node *temp = this->head; this->head = this->head->getNext(); delete temp; } else { throw std::range_error("List is empty!"); } return value; } }; // 保留C风格写法的修正版append函数 void append(Node** head_ref, int new_data) { Node* new_node = new Node(new_data); if (*head_ref == NULL) { *head_ref = new_node; return; } Node *last = *head_ref; while (last->next != NULL) { last = last->next; } last->next = new_node; } void printList(Node* n) { while (n != NULL) { std::cout << n->value << " "; n = n->next; } } int main() { Node* head = NULL; int a; cout << "Please enter value 1#: "; cin >> a; append(&head, a); int b; cout << "Please enter value 2#: "; cin >> b; append(&head, b); int c; cout << "Please enter value 3#: "; cin >> c; append(&head, c); int d; cout << "Please enter value 4#: "; cin >> d; append(&head, d); cout<<"Created Linked list is: "; printList(head); // 释放C风格链表的堆内存 while (head != nullptr) { Node* temp = head; head = head->next; delete temp; } return 0; }
补充说明:
segmentation fault (core dumped)即段错误,是C/C++开发中最常见的运行时错误之一,90%以上的场景由三类问题触发:空指针/野指针解引用、数组/缓冲区越界访问、访问已经被释放的内存。遇到该错误时优先排查指针使用前是否做了有效性检查、内存访问是否超出边界即可快速定位问题。
内容的提问来源于stack exchange,提问作者SprYz
相关产品推荐
相关产品推荐

