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

双向链表重复元素删除代码报错:Thread 1: EXC_BAD_ACCESS (code=1, address=0x10) 原因排查

双向链表重复元素删除代码报错:Thread 1: EXC_BAD_ACCESS (code=1, address=0x10) 原因排查

嘿,我来帮你拆解这个报错的问题~你遇到的Thread 1: EXC_BAD_ACCESS本质是访问了非法内存,具体到你代码里的(index->leftLink->rightLink)=(index->rightLink);这一行,核心问题出在删除节点后的指针处理逻辑上,我给你一步步分析:

直接报错原因:野指针访问

你在内层循环找到重复节点后,把index赋值给temporaryStorer,修改完链表链接就直接free(temporaryStorer)了。但free之后,index已经变成了野指针(指向被操作系统回收的内存),而内层循环的下一次迭代还会执行index = index->rightLink——这时候你在访问一块已经失效的内存里的rightLink,完全是非法操作,大概率触发内存访问错误。

代码里的其他隐形问题

除了直接导致报错的野指针,你的代码还有两个潜在问题:

  • 内存泄漏风险:你把free(temporaryStorer)放在了if (index->rightLink != NULL)的分支里,这意味着如果index是链表最后一个节点(rightLink为NULL),你就不会释放这个重复节点,长期运行会造成内存泄漏。
  • 循环指针更新逻辑错误:删除节点后没有提前保存下一个节点的地址,导致无法正确推进循环。

修正后的代码

我调整了你的代码逻辑,解决了上述所有问题:

typedef struct NODE {
    struct NODE* leftLink;
    int info;
    struct NODE* rightLink;
} NODE;

NODE* deleteDuplicates(NODE* head){
    NODE* current;
    NODE* temporaryStorer;
    NODE* index;
    NODE* nextNode; // 新增临时变量,提前保存下一个节点地址

    if (head == NULL) {
        printf("List is empty\n");
        return head;
    } else {
        // 外层循环遍历每个节点
        for (current = head; current != NULL; current = current->rightLink) {
            // 内层循环遍历当前节点之后的所有节点
            for (index = current->rightLink; index != NULL;) { // 这里不再自动更新index,手动处理
                if (index->info == current->info) {
                    // 先保存下一个节点,避免free后丢失
                    nextNode = index->rightLink;
                    temporaryStorer = index;

                    // 修改前驱节点的右指针,跳过当前重复节点
                    index->leftLink->rightLink = nextNode;
                    // 如果不是最后一个节点,修改后继节点的左指针
                    if (nextNode != NULL) {
                        nextNode->leftLink = index->leftLink;
                    }
                    // 释放重复节点
                    free(temporaryStorer);
                    // 让index跳转到下一个节点,继续循环
                    index = nextNode;
                } else {
                    // 没有重复,正常移动index指针
                    index = index->rightLink;
                }
            }
        }
    }
    return head;
}

关键修正点说明

  1. 新增nextNode保存下一个节点:在删除index节点前先记录它的下一个节点地址,这样即使index被释放,也能正确推进循环,避免野指针。
  2. 手动控制index的更新:内层循环的index更新不再写在for循环头部,而是根据是否删除节点来处理,确保每次循环的index都是合法指针。
  3. 调整free的位置:把free(temporaryStorer)移到分支外面,确保所有重复节点都会被释放,不会出现内存泄漏。

备注:内容来源于stack exchange,提问作者Marc Newsom

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 14:24:35