C语言自定义struct实现成绩簿 打印异常仅输出第二组输入
核心问题点
代码存在4处直接引发异常的逻辑错误:
- 仅定义了单个
struct gradeID类型变量存储输入,未给学生结构体数组分配存储区,每次新输入都会覆盖上一次写入的内容,历史输入数据全部丢失 - 计数器变量
ctr未初始化,属于C语言未定义行为,计数结果完全不可控 - 数据写入逻辑顺序错误:输入循环全部结束后才执行单次写入操作,且
identifier指针未分配有效内存就被访问,触发野指针运行崩溃 - 已实现的
sort排序函数从未被调用,free(temps)内存释放逻辑写在return 0之后永远无法执行,且temps指向的动态内存全程未被使用,属于冗余代码
修复方案
- 删除全程未使用的
int *temps相关冗余代码,为结构体指针identifier分配可容纳10个struct gradeID元素的动态内存,添加内存分配失败的校验逻辑 - 初始化
ctr计数器初始值为0,每次用户输入完成后立刻将数据写入结构体数组对应下标位置,避免单变量覆盖历史数据 - 全部输入收集完成后,调用
sort函数对结构体数组按学生ID排序 - 打印结果时遍历结构体数组的每个元素输出,不再反复读取单变量中存储的最后一次输入内容
- 将内存释放逻辑调整到
return语句之前,程序退出前释放申请的结构体数组内存
gradebook.h(无需修改)
// gradebook.h struct gradeID { int id; char grades[25]; };
修正后的主程序代码
#include "gradebook.h" #include <stdio.h> #include <stdlib.h> void sort(struct gradeID *, int); int main(void) { int ctr = 0; // 计数器必须初始化 char contInput; int i; struct gradeID *identifier; const int MAX_STUDENT = 10; // 为学生结构体数组分配动态内存 identifier = (struct gradeID *)malloc(MAX_STUDENT * sizeof(struct gradeID)); if (identifier == NULL) { printf("Not enough memory!\n"); exit(1); } printf("\t\tGradebook Recorder\n"); printf("Input student IDs and grades.\n"); printf("These will be sorted by ID and printed.\n"); for(i = 0; i < MAX_STUDENT; i++) { printf("Input student ID:\n"); scanf(" %d", &identifier[i].id); // 直接写入数组对应位置,避免单变量覆盖 printf("Input grade:\n"); scanf(" %s", identifier[i].grades); ctr++; // 每成功录入一条记录计数+1 printf("Do you have more grades to enter?\n"); printf("Y/N\n"); scanf(" %c", &contInput); if(contInput == 'N' || contInput == 'n') { printf("Finalizing and printing input-\n\n"); break; } } // 调用排序函数 sort(identifier, ctr); printf("Grades Sorted by Student ID:\n\n"); printf("\tStudent ID: Student Grade: \n"); // 遍历数组打印所有有效记录 for(i = 0; i < ctr; i++) { printf("\t%d", identifier[i].id ); printf("\t%s\n", identifier[i].grades); } // 内存在return前释放 free(identifier); return 0; } void sort(struct gradeID identifier[], int counter) { int inner; int outer; struct gradeID temp; for(outer = 0; outer < counter - 1; ++outer) { for(inner = outer + 1; inner < counter; ++inner) { if(identifier[inner].id < identifier[outer].id) { temp = identifier[inner]; identifier[inner] = identifier[outer]; identifier[outer] = temp; } } } return; }
内容的提问来源于stack exchange,提问作者Starbeard
相关产品推荐
相关产品推荐

