自定义FIFO链表移除函数后调用get触发Thread 1: EXC_BAD_ACCESS错误
问题结论
是的,该崩溃问题完全由你自行实现的fifoqueue_remove函数导致。
具体报错原因
- 未维护队列的
size计数器:你删除节点后没有将队列的size字段减1,导致队列实际节点数和记录的长度不一致。当你通过自定义remove函数把队列所有节点清空后,size仍然显示大于0,此时调用库自带的fifoqueue_get函数会进入出队分支,直接读取已经为NULL的front_ptr,尝试访问其next_ptr成员时等价于访问空指针偏移8字节的地址,刚好匹配你收到的EXC_BAD_ACCESS (code=1, address=0x8)错误。 - 未维护队列的
back_ptr尾指针:如果删除的是队列最后一个节点,back_ptr会指向已经被释放的野内存,后续操作也会触发非法访问。 - 边界逻辑缺失:删除头节点且该节点是队列唯一节点时,没有同步将
back_ptr置为NULL,和库函数的队列维护逻辑不一致。
修复方案
修改后的fifoqueue_remove代码如下:
void fifoqueue_remove(Fifoqueue_Ptr queue_ptr, void * this_call) { Queue_Container_Ptr temp = queue_ptr->front_ptr; //make position head Queue_Container_Ptr prev = NULL; if (temp != NULL && temp->content_ptr == this_call){ //head is this this_call queue_ptr->front_ptr = temp->next_ptr; // 新增:如果删除的是唯一节点,将尾指针置空 if (queue_ptr->front_ptr == NULL) { queue_ptr->back_ptr = NULL; } free((char*) temp); // 新增:维护size计数器 queue_ptr->size--; return; } while (temp != NULL && temp->content_ptr != this_call){ prev = temp; temp = temp->next_ptr; } if (temp == NULL){ return; } prev->next_ptr = temp->next_ptr; // 新增:如果删除的是尾节点,更新尾指针 if (temp == queue_ptr->back_ptr) { queue_ptr->back_ptr = prev; } free((char*) temp); // 新增:维护size计数器 queue_ptr->size--; }
内容的提问来源于stack exchange,提问作者LYM
相关产品推荐
相关产品推荐

