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

单链表删除值小于后继节点元素时触发double free错误,如何解决?

单链表删除元素触发double free错误的问题排查

你编写的删除单链表中值小于后继节点元素的函数,触发free():double free detected in tcache 2错误,核心问题出在指针初始化和删除后的指针更新逻辑上,具体问题如下:

代码中的错误点

  • prev指针未初始化,处理首节点时访问非法内存:函数启动时curr指向链表头节点、next指向第二个节点,但prev未赋值属于野指针。如果首节点满足curr->num < next->num,执行prev->next=next会直接访问非法内存,破坏内存结构,后续操作必然出错。
  • 删除节点后的指针更新逻辑错误,引发重复释放:删除curr节点后,代码将curr赋值为prev并continue,此时next仍指向原来的后继节点。下一次循环会错误地用旧的next和新的curr(即prev)比较,后续操作可能重复处理节点,甚至释放已经被释放的内存,直接触发double free。
  • 未处理头节点被删除的场景:函数参数是值传递的指针,如果头节点被删除,main函数中的first指针不会同步更新,仍指向已释放的内存,存在潜在的内存访问风险。

修正后的代码

#include <iostream>
using namespace std;
struct Elem
{
    int num;
    Elem* next;
};

// 使用引用传递指针,确保头节点被删除时能同步更新外部指针
void deleteFromLinkedList(Elem* &list) { 
    Elem* curr = list;
    Elem* prev = nullptr;

    while (curr != nullptr && curr->next != nullptr)
    {
        Elem* nextNode = curr->next;
        if (curr->num < nextNode->num) {
            // 处理头节点被删除的情况
            if (prev == nullptr) {
                list = nextNode;
            } else {
                prev->next = nextNode;
            }
            delete curr;
            // 更新curr为后继节点,继续检查新节点
            curr = nextNode;
        } else {
            // 无需删除,正常移动指针
            prev = curr;
            curr = nextNode;
        }
    }
}

int main()
{
    Elem* first = nullptr, * last = nullptr, * p;
    int i;
    cout << "Enter any number or 0 to finish: ";
    cin >> i;
   
    while (i != 0)
    {
        p = new Elem;
        p->num = i;
        p->next = nullptr;
        if (first == nullptr)
        {
            first = last = p;
        }
        else
        {
            last->next = p;
            last = last->next;
        }
        cout << "Enter any number or 0 to finish: ";
        cin >> i;
    }
    deleteFromLinkedList(first);

    // 可选:打印处理后的链表验证结果
    Elem* temp = first;
    while (temp != nullptr) {
        cout << temp->num << " ";
        temp = temp->next;
    }
    cout << endl;

    // 释放剩余节点,避免内存泄漏
    temp = first;
    while (temp != nullptr) {
        Elem* toDelete = temp;
        temp = temp->next;
        delete toDelete;
    }
    first = nullptr;
    last = nullptr;

    return 0;
}

修正说明

  • 将函数参数改为Elem* &list引用传递,确保头节点被删除时,main函数中的first指针能同步更新。
  • 初始化prev为nullptr,明确区分头节点删除的场景。
  • 删除节点后,将curr更新为nextNode,继续检查新节点和它的后继,避免指针混乱。
  • 增加了链表剩余节点的释放逻辑,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 18:05:46