C语言queue_poll函数错误排查:无法取出队列尾元素
问题排查与修复
核心问题分析
你的代码存在三个关键问题,导致queue_poll无法正常工作:
1. queue_poll破坏队列结构,产生野指针
当前实现直接free最后一个节点,但未修改倒数第二个节点的next指针为NULL,导致悬空指针;更严重的是,当队列只有头节点时,你直接free了作为队列入口的queue指针(比如FCFS_queue),使其变为野指针,后续操作完全失效。
2. queue_add是头插法,与"取最后一个元素"的预期错位
queue_add的逻辑是把新元素插入到队列头部:每次将新对象放到头节点的object字段,原头节点的内容被移到新创建的节点并挂到next上。添加A-F后,队列结构为:
FCFS_queue -> object = F FCFS_queue -> next -> object = E ... 最后一个节点 -> object = A,next = NULL
此时queue_poll取出的是最早添加的A,而非你可能预期的最后添加的F。
3. queue_poll循环逻辑错误
你的循环只能找到最后一个节点,但无法处理头节点本身存储元素的情况,也没有维护队列的链接关系。
修复方案
根据你的需求,分两种场景给出修复代码:
场景1:取出队尾元素(最早添加的元素,如A)
保留头插法的队列结构,修改queue_poll找到倒数第二个节点,维护队列链接,且不释放作为入口的头节点:
void *queue_poll(queue_object *queue) { if (queue == NULL || (queue->next == NULL && queue->object == NULL)) { return NULL; } // 头节点直接存储元素,无后续节点 if (queue->next == NULL) { void *object = queue->object; queue->object = NULL; return object; } // 找到倒数第二个节点 queue_object *prev = queue; while (prev->next->next != NULL) { prev = prev->next; } queue_object *last_node = prev->next; void *object = last_node->object; free(last_node); prev->next = NULL; // 断开悬空指针 return object; }
场景2:取出队头元素(最后添加的元素,如F)
如果你的实际需求是栈式的"后进先出",修改queue_poll直接取头节点元素,并调整队列结构:
void *queue_poll(queue_object *queue) { if (queue == NULL || queue->object == NULL) { return NULL; } void *object = queue->object; queue_object *tmp = queue->next; if (tmp != NULL) { queue->object = tmp->object; queue->next = tmp->next; free(tmp); } else { queue->object = NULL; } return object; }
额外优化:改为标准FIFO队列(可选)
如果要实现标准的先进先出队列,修改queue_add为尾插法,确保新元素添加到队尾:
int queue_add(void *new_object, queue_object *queue) { if (queue == NULL || new_object == NULL) { return 1; } // 头节点为空,直接存入 if (queue->object == NULL) { queue->object = new_object; return 0; } queue_object *object = new_queue(); if (object == NULL) { return 1; } object->object = new_object; // 找到队尾节点 queue_object *tail = queue; while (tail->next != NULL) { tail = tail->next; } tail->next = object; return 0; }
此时queue_poll取出队头元素(最早添加的A),符合队列的FIFO特性。
内容的提问来源于stack exchange,提问作者checkchecker
相关产品推荐
相关产品推荐

