学生信息录入Bug:首位学生课程信息被覆盖问题求助
解决首位学生课程信息被覆盖的问题
问题根源
你遇到的这种仅首位学生课程信息被覆盖、后续正常的情况,几乎都是首位学生的多门课程指向了同一块内存空间,或者结构体的课程存储逻辑存在初始化漏洞。
常见错误及修复方案
1. 用全局/静态临时变量存课程,直接赋值指针
很多人图省事会用全局变量临时存储课程信息,然后把指针塞给学生结构体的课程字段——这会导致所有课程都指向同一块内存,新输入的内容自然会覆盖旧数据。比如:
// 错误写法 typedef struct { int id; int score; } Course; Course temp_course; // 全局临时变量,所有课程都指向它 typedef struct { char name[20]; Course* courses[5]; } Student; // 录入课程时的错误操作 void add_course(Student* s, int idx) { scanf("%d %d", &temp_course.id, &temp_course.score); s->courses[idx] = &temp_course; // 所有课程指向同一地址 }
修复方案:要么直接用结构体数组存储课程(避免指针),要么为每门课程单独分配内存:
// 方案1:结构体数组(最省心) typedef struct { char name[20]; Course courses[5]; // 直接存储结构体,无需指针 } Student; void add_course(Student* s, int idx) { scanf("%d %d", &s->courses[idx].id, &s->courses[idx].score); } // 方案2:动态分配内存 void add_course(Student* s, int idx) { s->courses[idx] = malloc(sizeof(Course)); scanf("%d %d", &s->courses[idx]->id, &s->courses[idx]->score); }
2. 首位学生的课程指针未初始化,指向同一块随机内存
如果代码中首位学生的课程指针未分配内存,直接使用野指针,刚好指向同一块临时内存;而后续学生的指针有正常malloc操作,就会出现这种差异。比如:
// 错误写法 Student students[10]; // 首位学生直接使用野指针 students[0].courses[0] = &temp_course; students[0].courses[1] = &temp_course; // 后续学生正常分配内存 students[1].courses[0] = malloc(sizeof(Course)); students[1].courses[1] = malloc(sizeof(Course));
修复方案:统一为所有学生的课程分配内存,或者直接使用结构体数组避免指针问题。
3. 录入时索引未递增,反复写入同一位置
如果录入首位学生第二门课程时,忘记递增课程索引,两次都往同一个数组位置写入,自然会覆盖之前的数据。比如:
// 错误写法 int idx = 0; // 录入第一门课 scanf("%d %d", &students[0].courses[idx].id, &students[0].courses[idx].score); // 录入第二门课,索引未递增 scanf("%d %d", &students[0].courses[idx].id, &students[0].courses[idx].score);
修复方案:每次录入完成后,记得将索引idx++,确保写入不同的数组位置。
快速排查方法
录入课程后打印每门课程的内存地址,如果地址相同,即可确认是指针指向同一块内存导致的覆盖:
printf("课程1地址:%p,课程2地址:%p\n", &students[0].courses[0], &students[0].courses[1]);
内容的提问来源于stack exchange,提问作者idan yossifov
相关产品推荐
相关产品推荐

