为什么我的C语言简单程序在case '2'的break语句处崩溃
程序分支退出时崩溃问题排查
我的程序刚好在case '2'的break语句处崩溃,该case下的代码都能正常执行,但到break语句就崩溃非常奇怪,理论上程序应该回到循环继续运行。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<stdbool.h> #define nullptr ((void*)0) typedef unsigned char byte; // 8位数值类型 #define max 255 #define cap 256 typedef struct Elemento Elemento; struct Elemento { char* valor; byte prioridade; bool isvalid; }; typedef struct { short comprimento; Elemento elementos[cap]; } Lista; void inicializa (Lista* q) { // 初始化队列 q->comprimento = 0; } void ordena (Lista *q) { short i; for (i = 1; i < q->comprimento; i ++) { Elemento e = q->elementos[i]; short j; for (j = i - 1; j >= 0 && q->elementos[j].prioridade < e.prioridade; j --) { strcpy(q->elementos[j + 1].valor, q->elementos[j].valor); q->elementos[j + 1].prioridade = q->elementos[j].prioridade; } q->elementos[j + 1] = e; } } void enfileira (Lista* q, Elemento *s, byte p) { // 元素入队 if (q->comprimento != cap) { q->elementos[q->comprimento].valor = (char *) malloc(strlen(s->valor)*sizeof(char)); strcpy(q->elementos[q->comprimento].valor, s->valor); q->elementos[q->comprimento].prioridade = p; q->elementos[q->comprimento].isvalid = true; q->comprimento ++; if (q->comprimento > 1) ordena(q); } } Elemento primeiro (Lista* q) { // 获取队首元素 Elemento e; if (q->comprimento != 0) { e.isvalid = true; strcpy(e.valor, q->elementos[0].valor); return e; } e.isvalid = false; return e; } Elemento remova (Lista* q) { // 队首元素出队 Elemento e; if (q->comprimento != 0) { e.isvalid = true; strcpy(e.valor, q->elementos[0].valor); byte i; for (i = 0; i < q->comprimento - 1; i ++) { strcpy(q->elementos[i].valor, q->elementos[i + 1].valor); q->elementos[i].prioridade = q->elementos[i + 1].prioridade; } q->comprimento --; return e; } e.isvalid = false; return e; } short comprimento (Lista* q) { // 获取队列长度 return q->comprimento; } void reinicializa (Lista* q) { // 重置队列 q->comprimento = 0; } void finaliza (Lista* q) { // 销毁队列 } int main () { Lista s; Elemento e; e.valor = nullptr; char *string = nullptr; float valor; byte prioridade; short buffer_tam, string_tam; byte input; do { printf("operacao: "); string_tam = getline(&string, &buffer_tam, stdin); switch (string[0]) { case '1': inicializa(&s); break; case '2': string_tam = getline(&e.valor, &buffer_tam, stdin); e.valor[string_tam - 1] = '\0'; scanf("%hhu", &prioridade); enfileira(&s, &e, prioridade); break; case '3': printf("%s\n", primeiro(&s).valor); break; case '4': printf("%s\n", remova(&s).valor); break; case '5': printf("%hi\n", comprimento(&s)); break; case '6': reinicializa(&s); break; case '7': finaliza(&s); break; } } while (string[0] != '0'); return 0; }
该问题可能在其他环境下无法复现,常规搜索也难以定位到对应原因。
问题根因与解决方案
- 调整分支判断逻辑无法解决问题:将switch替换为if语句后,程序仍然会在退出分支时崩溃
- 根因定位:输入处理逻辑混用getline和scanf,两种输入函数对缓冲区的处理逻辑不同,导致换行符残留、后续内存操作异常
- 修复方法:将case '2'中的scanf调用替换为getline读取优先级数值,程序即可正常运行
内容的提问来源于stack exchange,提问作者Lucas Cavalcante
相关产品推荐
相关产品推荐

