使用两个队列实现栈时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
相关产品推荐
相关产品推荐

