You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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但全程未使用,属于冗余代码。
  • 输出逻辑缺陷:重载的<<运算符中节点之间没有输出分隔符,最终打印的所有数值会连在一起,可读性差。
修复方案
  1. 调整append函数的执行顺序:将空指针判断逻辑移到指针解引用操作之前,禁止在确认指针有效前访问其指向的内存。
  2. 修正新节点创建逻辑:直接调用Node构造函数传入新数值和空指针初始化节点,不需要后续手动给节点成员赋值。
  3. 删除无用冗余代码,包括未使用的变量e、无效的节点成员手动赋值逻辑,补全输出分隔符。
  4. 补充链表内存释放逻辑,避免程序运行出现内存泄漏。

修复后的完整可运行代码如下:

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 17:21:22