单链表实现删除函数报EXC_BAD_ACCESS错误的原因与修复方法
错误含义解释
EXC_BAD_ACCESS (code=EXC_I386_GPFLT) 是典型的非法内存访问错误,通常由以下几种情况触发:
- 访问已经被释放的内存地址
- 解引用空指针/野指针
- 访问没有权限的内存区域
代码问题排查
你的删除函数存在多个逻辑错误,直接触发了内存访问异常:
- 核心错误:删除对象搞错,你匹配到的待删除节点是
position->next_ptr(也就是你定义的next变量),但代码错误释放了position节点,释放后下一轮循环判断position->next_ptr时直接访问野指针 - 逻辑遗漏:节点删除完成后没有做流程控制,既没有跳出循环,也没有正确更新当前遍历指针的位置
- 边界缺失:没有判断空队列的情况,如果队列为空
queue_ptr->front_ptr为NULL,直接访问position->next_ptr会触发空指针解引用 - 多余转换:
free函数接受void*类型参数,不需要强制转为char* - 功能缺失:原逻辑没有判断头节点本身就是待删除节点的情况,也没有同步更新队列尾指针,会导致队列后续入队出队逻辑异常
修复后的实现代码
void fifoqueue_remove(Fifoqueue_Ptr queue_ptr, void * this_call){ // 先处理空队列边界 if (queue_ptr == NULL || queue_ptr->front_ptr == NULL) { return; } // 单独处理头节点就是待删除节点的情况 Queue_Container_Ptr position = queue_ptr->front_ptr; if (position->content_ptr == this_call) { queue_ptr->front_ptr = position->next_ptr; free(position); // 如果头节点删除后队列为空,同步更新尾指针 if (queue_ptr->front_ptr == NULL) { queue_ptr->rear_ptr = NULL; } return; } // 遍历后续节点 while (position->next_ptr != NULL){ if (position->next_ptr->content_ptr == this_call){ Queue_Container_Ptr to_delete = position->next_ptr; position->next_ptr = to_delete->next_ptr; // 如果删除的是尾节点,同步更新尾指针 if (to_delete == queue_ptr->rear_ptr) { queue_ptr->rear_ptr = position; } free(to_delete); // 释放正确的待删除节点 break; // 如果需要删除所有匹配项直接删除本行即可 } position = position->next_ptr; } }
内容的提问来源于stack exchange,提问作者LYM
相关产品推荐
相关产品推荐

