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

自定义Queue ADT实现出现无限循环,请求排查问题原因

问题分析与修复

核心错误点

  1. 入队函数逻辑完全错误:当前enqueue用的是头插法(新节点放到链表头部),这是栈(后进先出)的实现逻辑,完全不符合队列(先进先出)的要求。同时tail指针的维护彻底失效:第一次入队时tail被正确赋值,但后续入队时tail始终停留在第一个入队的节点上,从未更新。
  2. 出队函数的致命问题:
    • 直接free(queue->tail)后,没有修改链表中指向该节点的前驱指针,导致链表出现悬空指针。
    • 调用find_last递归查找尾节点时,会访问已经被释放的内存(比如测试中11节点被free后,12节点的next仍指向它),触发未定义行为,直接导致无限循环或程序崩溃。

修复后的关键代码

修正enqueue函数(改为尾插法,符合队列FIFO逻辑)

void enqueue(Queue queue, int num){
    Item *temp = crea_item(num);
    if (queue->tail == NULL){ // 队列为空时,头尾指向同一个节点
        queue->head = temp;
        queue->tail = temp;
    } else { // 队列非空时,新节点追加到尾部并更新tail
        queue->tail->next = temp;
        queue->tail = temp;
    }
    queue->size++;
}

修正dequeue函数(无需递归找尾,直接维护链表头部)

int dequeue(Queue queue){
    if (isQueueEmpty(queue)) {
        printf("Queue is empty!");
        exit(-1);
    }
    Item *temp = queue->head;
    int result = temp->num;
    queue->head = queue->head->next;
    // 队列清空时同步更新tail为NULL
    if (queue->head == NULL) {
        queue->tail = NULL;
    }
    free(temp);
    queue->size--;
    return result;
}

移除冗余函数

修正后的队列逻辑不需要递归查找尾节点,直接删除recursive_last和find_last两个函数即可。

验证效果

修改后运行你的测试代码main.c,会正常输出you did it!!,且队列的先进先出逻辑完全正确:入队11、12后,出队的结果是11,符合队列的预期行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 01:35:09