C语言结构体指针使用问题:程序输入首项后报错求助
问题分析与解决方案
核心问题1:野指针引发内存访问错误
你的STU结构体中firstname和lastname是字符指针,但从未为它们分配有效内存空间。直接用fgets或gets_s向这些未初始化的指针写入数据,会触发非法内存访问,对应你看到的退出码-1073741819(Windows平台的STATUS_ACCESS_VIOLATION错误)。
核心问题2:嵌套循环导致逻辑越界
main函数已经通过循环调用stuinfo遍历所有学生,但stuinfo内部又做了一次N次循环。这会导致:
- 每次调用
stuinfo都会重复处理N个学生,而非当前传入的单个学生 - 当循环变量
i>0时,pstudent+i会超出student数组的边界,再次引发内存错误
修复后的完整代码
#include <stdio.h> #include <string.h> // 用于strchr函数 #define N 10 #define NAME_MAX_LEN 99 // 定义名字的最大长度(含终止符) typedef struct { char firstname[NAME_MAX_LEN + 1]; // 用固定数组替代指针,避免内存分配问题 char lastname[NAME_MAX_LEN + 1]; unsigned int id; unsigned int gpa; } STU; void stuinfo(STU* pstudent, unsigned int student_idx); int main() { STU student[N]; printf_s("The number of students is %d.\n\n", N); for (unsigned int i = 0; i < N; i++) { stuinfo(&student[i], i + 1); // 传入单个学生的地址和序号 } // 可选:打印输入结果验证 printf_s("\n--- Student List ---\n"); for (unsigned int i = 0; i < N; i++) { printf_s("%d. %s %s | ID: %u | GPA: %u\n", i+1, student[i].firstname, student[i].lastname, student[i].id, student[i].gpa); } return 0; } void stuinfo(STU* pstudent, unsigned int student_idx) { // 读取名字并处理换行符 printf_s("Enter the first name of student %d : ", student_idx); fgets(pstudent->firstname, NAME_MAX_LEN + 1, stdin); char* newline = strchr(pstudent->firstname, '\n'); if (newline) *newline = '\0'; printf_s("Enter the last name of student %d : ", student_idx); fgets(pstudent->lastname, NAME_MAX_LEN + 1, stdin); newline = strchr(pstudent->lastname, '\n'); if (newline) *newline = '\0'; // 读取ID和GPA,处理输入残留的换行符 printf_s("Enter the ID of student %d : ", student_idx); scanf_s("%u", &pstudent->id); printf_s("Enter the GPA of student %d : ", student_idx); scanf_s("%u", &pstudent->gpa); // 清空scanf_s留下的换行符,避免影响下一次fgets while (getchar() != '\n'); }
关键修复说明
- 替换指针为固定数组:将结构体中的
char*改为char[],每个学生的名字直接拥有固定内存空间,彻底避免野指针问题。 - 移除嵌套循环:
stuinfo仅负责处理单个学生的信息,main的循环负责遍历所有学生,逻辑更清晰。 - 处理输入残留字符:
fgets会读取输入时的换行符,需手动替换为字符串终止符;scanf_s读取后会留下换行符,需用getchar()清空,避免干扰后续输入。 - 补充完整字段输入:原代码未处理
id和gpa字段,修复后补充了完整的输入流程。
如果需要使用动态内存分配(比如名字长度不固定),可以在stuinfo中用malloc分配内存,记得在程序结束前释放:
// 结构体恢复为指针定义 typedef struct { char* firstname; char* lastname; unsigned int id; unsigned int gpa; } STU; // 在stuinfo中分配内存 pstudent->firstname = malloc(NAME_MAX_LEN + 1); pstudent->lastname = malloc(NAME_MAX_LEN + 1); // 检查内存分配是否成功 if (!pstudent->firstname || !pstudent->lastname) { printf_s("Memory allocation failed!\n"); exit(1); } // 程序结束前释放内存 for (unsigned int i = 0; i < N; i++) { free(student[i].firstname); free(student[i].lastname); }
内容的提问来源于stack exchange,提问作者Lemony_79
相关产品推荐
相关产品推荐

