双向链表删除节点触发Segmentation fault问题求助
双向链表Segmentation Fault问题排查
我在操作双向链表时持续出现Segmentation fault错误,该错误似乎由remove()和size()函数引发。调试时发现传入remove()的pos参数与main函数中传入的不一致,相关代码如下:
头文件 linked_list.hpp
#ifndef linked_list_hpp #define linked_list_hpp #include <stdio.h> class linked_list { private: class Node { public: double data; Node *next; Node *prev; Node(double data); }; Node *head; Node *tail; public: size_t size() const; linked_list(); double back() const; double at(size_t index) const; // 修正参数类型 void push_back(double value); bool is_empty() const; void print() const; void remove(size_t pos); // 修正参数类型 }; #endif /* linked_list_h */
实现文件 linked_list.cpp
#include "linked_list.h" #include <iostream> #include <stdexcept> #include <algorithm> linked_list::linked_list(){ head = nullptr; tail = nullptr; } linked_list::Node::Node(double data){ this->data = data; this->next = nullptr; this->prev = nullptr; } bool linked_list::is_empty() const{ return (head == nullptr && tail == nullptr); } double linked_list::back() const { if (is_empty()) { throw std::out_of_range("Empty list"); } return tail->data; } double linked_list::at(size_t index) const{ if (index >= size()) { throw std::out_of_range("Index out of range"); } size_t i = 0; Node* curr = head; while(curr != nullptr && i != index){ curr = curr->next; i++; } return curr->data; } void linked_list::remove(size_t pos) { if (pos >= size()) { throw std::out_of_range("Index out of range"); } Node* curr = head; for (size_t i = 0; i < pos; i++) { curr = curr->next; } // 处理前驱节点 if (curr->prev != nullptr) { curr->prev->next = curr->next; } else { // 删除的是头节点,更新head head = curr->next; } // 处理后继节点 if (curr->next != nullptr) { curr->next->prev = curr->prev; } else { // 删除的是尾节点,更新tail tail = curr->prev; } delete curr; // 链表为空时,确保head和tail都置空 if (head == nullptr) { tail = nullptr; } } void linked_list::push_back(double value){ Node* new_node = new Node(value); if(is_empty()){ head = new_node; tail = new_node; return; } tail->next = new_node; new_node->prev = tail; tail = new_node; } size_t linked_list::size() const { size_t elements = 0; Node* temp = head; while (temp != nullptr) { elements++; temp = temp->next; } return elements; } void linked_list::print() const{ Node *temp = head; while (temp != nullptr) { std::cout << temp->data << " "; temp = temp->next; } std::cout << std::endl; }
主文件 main.cpp
#include <iostream> #include "linked_list.h" #include <cstdlib> #include <ctime> #include <chrono> int main() { linked_list ls1; auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count(); srand(seed); ls1.push_back(0); for (int i = 1; i < 50; i++) { int last_num = ls1.back(); int next_num = rand() % 5 + last_num + 1; ls1.push_back(next_num); } // 要删除索引25的元素,直接传入索引值 ls1.remove(25); // 如果需要按值删除,需新增对应函数,比如void remove_value(double value) // 实现逻辑为遍历链表找到对应值的节点再执行删除操作 ls1.print(); return 0; }
问题根源与修复说明
- 核心用法错误:main函数中
ls1.remove(list1_at_index25);传入的是节点的数值,但remove()函数设计为接收索引位置,参数完全不符合预期,直接引发越界访问导致Segmentation fault。 - 参数类型错误:
remove()和at()的参数使用double不合理,索引是整数类型,应改为size_t(匹配容器大小的无符号整数)或int,避免浮点数精度丢失引发的索引错误。 - 尾节点更新缺失:原
remove()函数删除最后一个节点时未更新tail指针,导致后续back()等函数访问已释放的内存地址。 - 空链表处理不完善:删除最后一个节点后,未将
head和tail同时置为nullptr,可能导致is_empty()判断失效。
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

