双队列实现的dequeue函数出现段错误,原因是什么及有何替代方案?
段错误触发原因
- 判断逻辑误用赋值运算符代替相等判断:代码中
if(Q1->rear=NULL)实际是将Q1的rear指针直接赋值为NULL,而非判断Q1是否为空。后续访问Q1->rear->next等价于访问空指针的成员,直接触发段错误。同理下方if(Q2->front=NULL)也存在相同问题,应改为==做相等判断。 - 出队后未维护Q1的rear指针有效性:当Q1中仅剩1个元素时,出队操作释放了原front节点(也就是rear指向的节点),此时Q1->rear变成野指针,同时Q1->front会被置为NULL,代码未同步将Q1->rear置为NULL,后续访问野指针的next成员必然触发段错误。
- 未做Q2非空校验就操作Q2成员:当count>=3但Q2已经为空时,直接访问
Q2->front或者修改Q2->front也会触发空指针访问。
可正常运行的实现方案
需求为每次从Q1出队1个元素后,若Q2不为空,就把Q2的队首元素移到Q1队尾,修正后的代码如下:
int dequeue(queue* Q1, queue* Q2) { node* temp; // 判断Q1是否为空,无元素可出队直接返回 if (Q1->front == NULL) { return 0; } // 执行Q1出队操作 temp = Q1->front; Q1->front = Q1->front->next; // 出队后Q1为空则同步置空rear指针,避免野指针 if (Q1->front == NULL) { Q1->rear = NULL; } free(temp); count--; // Q2非空时才执行元素移动操作 if (Q2->front != NULL) { node* move_node = Q2->front; Q2->front = Q2->front->next; // Q2出队后为空则同步置空rear指针 if (Q2->front == NULL) { Q2->rear = NULL; } // 将取出的Q2节点加入Q1队尾 move_node->next = NULL; if (Q1->rear == NULL) { // Q1当前为空的特殊情况,front和rear都指向新节点 Q1->front = move_node; Q1->rear = move_node; } else { Q1->rear->next = move_node; Q1->rear = move_node; } } return 1; }
该实现去掉了冗余的count分支判断,统一处理所有出队场景,所有指针操作前都做了非空校验,出队后同步维护队列的front和rear指针有效性,避免野指针和空指针访问,鲁棒性更强。
内容的提问来源于stack exchange,提问作者Mohamed Elkasimi
相关产品推荐
相关产品推荐

