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

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;
    }
}

三、其他潜在问题修复(可选)

  1. 内存释放不匹配:原代码用free释放new创建的节点,应改用delete(new和delete配对,malloc和free配对)
  2. Display函数逻辑错误:原代码使用static Node* temp,导致第一次调用后指针无法重置,修改为每次从头遍历:
void Display() {
    Node* temp = head;
    while (temp != nullptr) {
        cout << temp->data << "->";
        temp = temp->next;
    }
    cout << "NULL" << endl;
}
  1. Erase函数逻辑错误:原代码仅释放第一个节点,修改为遍历释放所有节点:
void Erase() {
    Node* current = head;
    while (current != nullptr) {
        Node* nextNode = current->next;
        delete current;
        current = nextNode;
    }
    head = nullptr;
}

内容的提问来源于stack exchange,提问作者ES JOKER

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:01:23