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

使用两个队列实现栈时push功能异常及队列出队(dequeue)异常排查求助

使用两个队列实现栈时push功能异常及队列出队(dequeue)异常排查求助

兄弟,我仔细看了你的代码和运行输出,问题主要集中在push函数的两个关键错误上,咱们一步步拆解解决:

1. 数据乱码的核心原因:enqueue传参完全错了

你在push里的两个while循环中,调用enqueue(&qu, q->head)和enqueue(&q, qu->head)时,传的是节点本身的指针(Node*类型),但原有的enqueue函数是用来存储业务数据的(也就是Node->data)。你现在把节点的内存地址存进了队列,后面用*(int*)解引用时,自然会把地址当成int值打印,就出现了那些莫名其妙的数字(比如2151934760)。

而且你原来的写法先enqueue再dequeue,逻辑上有风险——dequeue之后q->head已经指向了下一个节点,你之前访问的q->head已经是待释放的节点了,虽然第一次循环不会崩,但后续很容易出问题。

修正后的第一个循环应该改成这样:

while (!isQueueEmpty(q)) {
    void* data = dequeue(q);  // 先出队拿到数据,同时自动移除原节点
    enqueue(&qu, data);       // 把真实的数据存入qu队列
    printf("eleq: %d\n", *((int *)data));
}

2. 第二个队列循环的无限循环问题:同样的传参错误+逻辑冗余

你第二个循环里不仅犯了同样的传参错误,手动调用dequeue(qu)的位置也不对,导致队列的节点没有被正确移除,才会触发无限循环。修正后的第二个循环应该是:

while (!isQueueEmpty(qu)) {
    void* data = dequeue(qu);
    enqueue(&q, data);
    // 要是需要打印可以打开下面的注释
    // printf("elequ: %d\n", *((int *)data));
}

这样每次从qu出队拿到数据,再存入q,同时qu的节点会被dequeue正确释放并移动head,isQueueEmpty就能正确判断队列是否为空,不会出现无限循环。

修正后的完整push函数

void push(void *item) {
    printf("reeter here\n");
    // 将q中所有元素转移到qu
    while (!isQueueEmpty(q)) {
        void* data = dequeue(q);
        enqueue(&qu, data);
        printf("eleq: %d\n", *((int *)data));
    }
    // 将新元素加入空的q
    enqueue(&q, item);
    // 将qu中的元素移回q
    while (!isQueueEmpty(qu)) {
        void* data = dequeue(qu);
        enqueue(&q, data);
    }
    printf("q:\n");
    printQueue(q);
    printf("qu:\n");
    printQueue(qu);
    printf("reached end\n");
}

这样修改后,数据会被正确存储到队列中,qu队列也会在每次push后被清空,不会出现你遇到的乱码和无限循环问题啦。

备注:内容来源于stack exchange,提问作者shinny.dogma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 09:39:35