二叉搜索树学生系统中动态添加课程结构体数组的问题排查
二叉搜索树学生管理系统课程添加模块问题排查与优化建议
问题描述
正在实现基于二叉搜索树的学生管理系统,在添加课程模块尝试通过动态分配Disciplina结构体数组存储学生课程信息时运行出错,核心代码片段如下:
novo -> disciplinas = malloc(sizeof(Disciplina) * numdisciplinas); for (int i = 0; i < numdisciplinas; i++){ printf("Digite o nome da disciplina: "); scanf("%s",&novo -> disciplinas[i] -> nome); scanf("%c"); printf("\nDigite o codigo da disciplina: "); scanf("%d",&novo -> disciplinas[i] -> codigo); printf("\nDigite a nota final da disciplina: "); scanf("%f",&novo -> disciplinas[i] -> nota); }
错误原因分析
- 结构体成员访问错误:
novo->disciplinas是动态分配的Disciplina类型数组,disciplinas[i]是数组中的结构体实例(非指针),必须用.访问成员,而非->。当前代码用disciplinas[i]->nome会直接导致非法内存访问。 - 输入缓冲区处理不当:
scanf("%c");未指定接收变量,无法正确清空输入缓冲区的换行符,会导致后续scanf读取异常。 - 未检查内存分配结果:
malloc可能分配失败返回NULL,后续直接操作会引发程序崩溃。
修复后的代码
// 先检查内存分配是否成功 novo->disciplinas = malloc(sizeof(Disciplina) * numdisciplinas); if (novo->disciplinas == NULL) { printf("内存分配失败\n"); // 根据实际逻辑处理错误,比如返回错误码或终止程序 return; } for (int i = 0; i < numdisciplinas; i++) { printf("Digite o nome da disciplina: "); // 使用.访问结构体成员 scanf("%s", novo->disciplinas[i].nome); // 清空输入缓冲区残留的换行符 while(getchar() != '\n'); printf("\nDigite o codigo da disciplina: "); scanf("%d", &novo->disciplinas[i].codigo); while(getchar() != '\n'); printf("\nDigite a nota final da disciplina: "); scanf("%f", &novo->disciplinas[i].nota); while(getchar() != '\n'); }
更简便的课程添加实现方式
- 改用链表存储课程:避免数组的固定大小限制,添加课程时动态创建
Disciplina节点并插入链表,无需预先指定课程数量,灵活性更高。 - 封装课程输入逻辑:将单个课程的输入逻辑封装为独立函数,代码结构更清晰:
Disciplina criarDisciplina() { Disciplina disc; printf("Digite o nome da disciplina: "); fgets(disc.nome, sizeof(disc.nome), stdin); // 移除fgets读取的换行符 size_t len = strlen(disc.nome); if (len > 0 && disc.nome[len-1] == '\n') { disc.nome[len-1] = '\0'; } printf("\nDigite o codigo da disciplina: "); scanf("%d", &disc.codigo); while(getchar() != '\n'); printf("\nDigite a nota final da disciplina: "); scanf("%f", &disc.nota); while(getchar() != '\n'); return disc; }
调用时直接在循环中赋值:novo->disciplinas[i] = criarDisciplina();
3. 优化字符串输入:用fgets替代scanf("%s"),支持读取带空格的课程名称,避免输入截断问题。
内容的提问来源于stack exchange,提问作者Entony Maxwell
相关产品推荐
相关产品推荐

