队列(Queue)代码报错求助:Read access violation,front为nullptr
队列代码Remove操作触发空指针访问错误的解决方案
问题概述
编写的C++队列代码编译正常,但选择remove操作时触发错误:Exception thrown: Read access violation. front was nullptr,期望调用remove_Queue时能移除队列头部元素,相关代码如下:
typedef int Item; const int MAX_QUEUE = 10; int cont = 0; typedef int Item; struct Queue { Item value; Queue* next; }; Queue* front; Queue* back; Queue* tmp; bool insert_Queue( Item& i, Queue* front, Queue* back,Item x) { tmp = new Queue; tmp->next = NULL; tmp->value = 1; front = back = tmp; return true; } bool remove_Queue(Item& i, Queue* front, Queue* back, int& x) { if (front == NULL) return false; i = front->value; x --; Queue* tmp = front; front = front->next; delete tmp; if (x == 0) back = NULL; return true; } int main() { while (1) { printf(" Choose "); printf("1.Stack 2.Queue 3.List "); printf("Choose: "); scanf_s("%d", &choice1); while (1) { printf(" Operations performed by Queue"); printf(" 1.Insert 2.Remove 3.Print queue 4.Pop from start 5.Count 6.Is empty? 7.Delete Queue 8.Exit"); printf(" Enter the choice: "); scanf_s("%d", &choice2); switch (choice2) { case 1: { int i; printf("input value:"); scanf_s("%d", &i); insert_Queue(i, front, back, cont); x += 1; break; } case 2: { Item val; printf("input value:"); scanf_s("%d", &val); remove_Queue(val, front, back, x); break; } case 3: { print_Queue(front); break; } case 4: { break; } case 5: { count_Queue(x); break; } case 6: { isЕmpty_Queue(front); break; } case 7: { delete_Queue(front, back, x); break; } case 8: { exit(0); } default: printf(" Invalid choice!! "); } } } return 0; }
错误根源
- 传值调用导致全局指针未更新:
insert_Queue和remove_Queue中,front和back是按值传递的形参,函数内的修改不会同步到全局指针,队列始终未被正确初始化,front一直为nullptr。 - 插入逻辑错误:
insert_Queue每次插入都直接覆盖front和back,没有链接到原有队列尾部,还硬编码value=1,未使用传入的实际值。 - 变量未声明/初始化:
main里的choice1、choice2、x均未声明,x作为计数变量也未初始化,触发未定义行为。 - Remove操作逻辑冗余:队列是FIFO结构,移除队头不需要用户输入值,当前输入逻辑完全多余。
修复后的完整代码
#include <cstdio> #include <cstdlib> typedef int Item; struct Queue { Item value; Queue* next; }; // 全局队列指针,初始化为空 Queue* front = nullptr; Queue* back = nullptr; // 插入元素到队列尾部 bool insert_Queue(Item i) { Queue* tmp = new Queue; tmp->next = nullptr; tmp->value = i; // 使用传入的实际值 if (front == nullptr) { // 队列为空时,头尾都指向新节点 front = back = tmp; } else { // 队列非空时,链接到尾部并更新尾指针 back->next = tmp; back = tmp; } return true; } // 移除队头元素 bool remove_Queue(Item& i, int& count) { if (front == nullptr) { printf("队列已空,无法移除元素。\n"); return false; } // 获取队头值 i = front->value; count--; Queue* tmp = front; front = front->next; delete tmp; // 队列清空时同步更新尾指针 if (count == 0) { back = nullptr; } printf("已移除元素:%d\n", i); return true; } // 打印队列所有元素 void print_Queue(Queue* front) { if (front == nullptr) { printf("队列为空。\n"); return; } Queue* current = front; printf("队列元素:"); while (current != nullptr) { printf("%d ", current->value); current = current->next; } printf("\n"); } // 输出队列元素数量 void count_Queue(int count) { printf("队列共有 %d 个元素。\n", count); } // 判断队列是否为空 void isEmpty_Queue(Queue* front) { if (front == nullptr) { printf("队列为空。\n"); } else { printf("队列非空。\n"); } } // 删除整个队列,释放内存 void delete_Queue(Queue*& front, Queue*& back, int& count) { Queue* current = front; while (current != nullptr) { Queue* next = current->next; delete current; current = next; } front = back = nullptr; count = 0; printf("队列已清空。\n"); } int main() { int choice1, choice2; int queue_count = 0; // 初始化队列元素计数 while (1) { printf(" 选择操作类型\n"); printf("1.栈 2.队列 3.链表\n"); printf("请选择:"); scanf_s("%d", &choice1); if (choice1 != 2) { printf("当前仅修复队列相关操作,请选择2。\n"); continue; } while (1) { printf("\n队列操作选项\n"); printf("1.插入元素 2.移除队头\n"); printf("3.打印队列 4.弹出队头(同移除)\n"); printf("5.统计数量 6.判断是否为空\n"); printf("7.清空队列 8.退出\n"); printf("\n请输入选项:"); scanf_s("%d", &choice2); switch (choice2) { case 1: { int i; printf("请输入要插入的值:"); scanf_s("%d", &i); insert_Queue(i); queue_count += 1; break; } case 2: { Item val; // 移除操作直接删除队头,无需输入值 remove_Queue(val, queue_count); break; } case 3: { print_Queue(front); break; } case 4: { Item val; remove_Queue(val, queue_count); break; } case 5: { count_Queue(queue_count); break; } case 6: { isEmpty_Queue(front); break; } case 7: { delete_Queue(front, back, queue_count); break; } case 8: { // 退出前清理队列内存 delete_Queue(front, back, queue_count); exit(0); } default: printf("\n\n无效选项!请重新输入。\n\n"); } } } return 0; }
关键修复点说明
- 指针传引用:将
insert_Queue、remove_Queue、delete_Queue中的front、back改为传引用(Queue*&),确保函数内的修改能同步到全局指针。 - 修正插入逻辑:区分队列为空/非空场景,正确链接新节点到队列尾部,使用传入的实际值作为节点值。
- 变量规范:在
main中声明所有用到的变量,初始化队列计数queue_count为0。 - 简化Remove操作:移除多余的用户输入步骤,符合队列FIFO的核心特性。
- 补充缺失函数:实现
print_Queue、isEmpty_Queue等缺失函数,保证代码可完整运行。
内容的提问来源于stack exchange,提问作者JAJAJa Jajajaaa
相关产品推荐
相关产品推荐

