You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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');
}

关键修复说明

  1. 替换指针为固定数组:将结构体中的char*改为char[],每个学生的名字直接拥有固定内存空间,彻底避免野指针问题。
  2. 移除嵌套循环:stuinfo仅负责处理单个学生的信息,main的循环负责遍历所有学生,逻辑更清晰。
  3. 处理输入残留字符:fgets会读取输入时的换行符,需手动替换为字符串终止符;scanf_s读取后会留下换行符,需用getchar()清空,避免干扰后续输入。
  4. 补充完整字段输入:原代码未处理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:31:23