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

C++自定义链表实现赋值运算符报double free错误该如何解决?

问题根因分析
  • 缺失自定义拷贝构造函数,触发浅拷贝
    你测试代码中的Linkedlist b = a;属于拷贝初始化,调用的是拷贝构造函数而非你实现的赋值运算符。C++编译器在用户未自定义拷贝构造时会生成默认浅拷贝,直接将a的head、tail、size成员按字节复制给b,导致两个对象的head指向同一块堆内存。程序退出时b先析构释放了所有节点内存,a析构时再次释放同一块内存,直接触发double free错误。
  • 赋值运算符实现存在逻辑漏洞
    就算后续调用赋值运算符(比如写b = a;),现有实现也会触发异常:
    1. 未处理自赋值场景:如果执行a = a,开头的clear()会直接清空当前对象的所有节点,后续拷贝源已经为空,逻辑完全错误
    2. 尾节点处理错误:循环遍历右值链表时,每复制一个节点都会提前new下一个节点,循环结束后会多生成一个无数据的冗余节点,且没有将尾节点的next设为NULL,也没有更新当前对象的tail和size成员,会导致链表遍历、析构逻辑异常
修复方案

1. 实现自定义拷贝构造函数

Linkedlist::Linkedlist(const Linkedlist &l) {
    if (l.empty()) {
        head = tail = NULL;
        size = 0;
        return;
    }
    size = l.size;
    Node *iterRight = l.head;
    head = new Node;
    Node *iterLeft = head;
    while (iterRight != NULL) {
        iterLeft->data = iterRight->data;
        // 仅非最后一个节点时新建下一个节点
        if (iterRight->next != NULL) {
            iterLeft->next = new Node;
            iterLeft->next->prev = iterLeft;
            iterLeft = iterLeft->next;
        } else {
            iterLeft->next = NULL;
        }
        iterRight = iterRight->next;
    }
    tail = iterLeft;
}

2. 修复赋值运算符实现

Linkedlist &Linkedlist::operator=(const Linkedlist &l) {
    // 优先处理自赋值场景
    if (this == &l) {
        return *this;
    }
    clear();
    if (l.empty()) {
        head = tail = NULL;
        size = 0;
        return *this;
    }
    size = l.size;
    Node *iterRight = l.head;
    head = new Node;
    Node *iterLeft = head;
    while (iterRight != NULL) {
        iterLeft->data = iterRight->data;
        if (iterRight->next != NULL) {
            iterLeft->next = new Node;
            iterLeft->next->prev = iterLeft;
            iterLeft = iterLeft->next;
        } else {
            iterLeft->next = NULL;
        }
        iterRight = iterRight->next;
    }
    tail = iterLeft;
    return *this;
}

3. 优化带参构造(修复原有内存泄漏问题)

原有带参构造最后会生成一个冗余节点未释放,修复后逻辑更严谨:

Linkedlist::Linkedlist(unsigned int n) {
    size = n;
    tail = NULL;
    if (n == 0) {
        head = NULL;
        return;
    }
    head = new Node;
    Node *iter = head;
    for(int i = 0; i < n; i++) {
        iter -> data = i;
        if (i != n-1) {
            iter -> next = new Node;
            iter -> next -> prev = iter;
            iter = iter -> next;
        } else {
            iter->next = NULL;
        }
    }
    tail = iter;
}

内容的提问来源于stack exchange,提问作者Drake Ford

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:15:06