C++链表下标运算符重载实现及拷贝构造正确性排查求助
链表下标运算符重载段错误与拷贝构造函数修复
在DSA链表作业中,下标运算符重载运行时触发段错误,同时拷贝构造函数未实现深拷贝,以下是问题分析与修复方案:
一、下标运算符重载的问题与修复
原代码问题
原重载逻辑完全错误,且未处理空链表场景:
void operator[](int i) { head->data = i; }
- 当链表为空(如
main中刚创建的LinkedList L{}),head为NULL,直接访问head->data会触发段错误 - 逻辑不符合下标运算符的预期:下标运算符应通过索引访问对应位置的元素,而非修改头节点数据
正确实现
重载下标运算符需支持读写操作,并添加边界检查,返回元素的引用:
// 非const版本,支持读写 int& operator[](int index) { if (index < 0) { throw out_of_range("索引不能为负数"); } Node* temp = head; int current = 0; // 遍历到目标索引的节点 while (temp != nullptr && current < index) { temp = temp->next; current++; } if (temp == nullptr) { throw out_of_range("索引超出链表范围"); } return temp->data; } // const版本,供const对象使用,仅支持读 const int& operator[](int index) const { if (index < 0) { throw out_of_range("索引不能为负数"); } Node* temp = head; int current = 0; while (temp != nullptr && current < index) { temp = temp->next; current++; } if (temp == nullptr) { throw out_of_range("索引超出链表范围"); } return temp->data; }
在main中使用示例:
LinkedList L; L.InsertAtEnd(10); L.InsertAtEnd(20); L.InsertAtEnd(30); // 读操作 cout << L[1] << endl; // 输出20 // 写操作 L[1] = 25; L.Display(); // 输出10->25->30->NULL
二、拷贝构造函数的问题与修复
原代码问题
原拷贝构造函数是浅拷贝:
LinkedList(LinkedList& S) { head = S.head; }
两个链表的head指向同一内存区域,当其中一个链表销毁或修改节点时,会导致另一个链表的指针失效,违反深拷贝要求。
正确实现
遍历原链表,逐个创建新节点,实现深拷贝:
// 深拷贝构造函数,参数为const引用 LinkedList(const LinkedList& S) { head = nullptr; if (S.head == nullptr) { return; } // 拷贝头节点 head = new Node(S.head->data); Node* destTemp = head; Node* srcTemp = S.head->next; // 遍历原链表,拷贝剩余节点 while (srcTemp != nullptr) { destTemp->next = new Node(srcTemp->data); destTemp = destTemp->next; srcTemp = srcTemp->next; } }
三、其他潜在问题修复(可选)
- 内存释放不匹配:原代码用
free释放new创建的节点,应改用delete(new和delete配对,malloc和free配对) - Display函数逻辑错误:原代码使用
static Node* temp,导致第一次调用后指针无法重置,修改为每次从头遍历:
void Display() { Node* temp = head; while (temp != nullptr) { cout << temp->data << "->"; temp = temp->next; } cout << "NULL" << endl; }
- Erase函数逻辑错误:原代码仅释放第一个节点,修改为遍历释放所有节点:
void Erase() { Node* current = head; while (current != nullptr) { Node* nextNode = current->next; delete current; current = nextNode; } head = nullptr; }
内容的提问来源于stack exchange,提问作者ES JOKER
相关产品推荐
相关产品推荐

