链表学生管理系统更新/搜索异常:仅能读取首位节点
C语言学生管理系统位置操作函数崩溃问题修复
问题描述
- 异常表现:
updateByPos和searchByPos函数仅能正常处理位置1的节点,操作位置2及以后节点时程序崩溃,错误码0xC0000005(访问违规),其余功能运行正常。 - 复现步骤:添加4个学生节点后,选择功能3编辑位置2节点,或功能4搜索位置2及以后节点,程序直接崩溃。
问题根源
代码存在低级笔误:在updateByPos、searchByPos及deleteByPos的循环条件中,误将循环变量i写成了数字1,导致循环变为无限循环:
- 原错误循环条件:
for(i=1; 1<pos;i++) - 后果:当
pos≥2时,循环条件永远为真,h会不断指向next直到变为空指针,后续解引用h->name或h->studno时触发空指针访问违规。
修复方案
将所有出错的循环条件中的数字1替换为循环变量i,同时修正其他潜在问题:
1. 修复updateByPos函数
void updateByPos(Student *h){ int n = count(h); int pos, i; printf("Enter Position to Edit: "); scanf("%d", &pos); if(pos>n){ printf("\nINDEX OUT OF BOUNDS"); }else if(pos>0){ char name[20]; // 修复循环条件:1 -> i for(i=1; i<pos;i++) h = h -> next; printline(); // 替换fflush(stdin)为标准缓冲区清理方式 while(getchar() != '\n'); printf("Enter New Name: "); // 修正scanf格式:去掉多余的s scanf("%[^\n]",h->name); printf("Record Updated Successfully"); } }
2. 修复searchByPos函数
void searchByPos(Student *h){ int n = count(h); int pos, i; printf("Enter Position to Search: "); scanf("%d", &pos); if(pos>n){ printf("\nINDEX OUT OF BOUNDS"); }else if(pos>0){ // 修复循环条件:1 -> i for(i=1; i<pos;i++) h= h -> next; printline(); printf(" STUDENT RECORD FOUND \n"); printline(); printf("%-10d%-20s%f\n", h->studno, h->name, h->per); printline(); } }
3. 修复deleteByPos函数
void deleteByPos(Student *h){ int n = count(h); int pos, i; Student *tmp; printf("Enter Position to Delete: "); scanf("%d", &pos); if(pos>n){ printf("\nINDEX OUT OF BOUNDS"); }else if(pos==1){ // To delete from first position tmp = h; head = h->next; free(tmp); printf("\nRECORD SUCCESSFULLY DELETED"); } else if (pos>0){ // 修复循环条件:1 -> i for (i=1; i<pos-1; i++) h = h ->next; tmp = h -> next; h -> next = h -> next -> next; free(tmp); printf("\nRECORD SUCCESSFULLY DELETED"); } }
4. 其他潜在问题修复(可选)
create函数中else分支未加花括号,补全以避免后续维护错误:
else { while(h->next != NULL) h = h-> next; h-> next =(Student*) malloc(sizeof(Student)); h-> next -> studno = studno; strcpy(h-> next ->name, name); h-> next -> per = per; h-> next -> next = NULL; }
- 替换所有
fflush(stdin)为while(getchar() != '\n');,因为fflush(stdin)是C标准未定义行为,不同编译器表现不一致。
验证
修复后,操作位置2及以后的节点时,程序可正常执行更新、搜索、删除操作,不再触发崩溃。
内容的提问来源于stack exchange,提问作者anna
相关产品推荐
相关产品推荐

