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

如何在不添加额外库的C代码中动态分配结构体数组?

问题分析与修正方案

你的代码在动态分配部分存在几个关键错误,下面逐一说明并给出修正后的完整实现:

核心错误点

  • 重复定义变量:同时声明了栈上的变长数组struct RegistroAluno P1[QuantidadeAlunos];和动态分配指针struct *P1,编译会直接报错,二者只能选其一,这里我们保留动态分配方式。
  • 指针类型错误:动态分配的指针必须明确结构体类型,应该是struct RegistroAluno *而非struct *;且malloc的返回值无需强制转换为(int *),C语言中void*可自动适配结构体指针类型。
  • sizeof参数错误:sizeof(struct)无法正确获取目标结构体的内存大小,必须指定具体结构体名sizeof(struct RegistroAluno)。
  • 缺少分配失败检查:malloc在内存不足时会返回NULL,直接访问会导致程序崩溃,必须添加检查逻辑。
  • 未释放动态内存:程序结束前需要用free()释放分配的内存,避免内存泄漏。

修正后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h> // 用于strchr处理换行符,属于标准库,不算额外库

struct RegistroAluno{
    int Matricula;
    char Nome[20];
    int AnoNascimento;
};

int main()
{
    int QuantidadeAlunos;
    
    printf("Quantos alunos serão armazenados?\n");
    scanf("%i", &QuantidadeAlunos);
    getchar(); // 清除scanf后留在缓冲区的换行符

    // 动态分配结构体数组
    struct RegistroAluno *P1 = malloc(QuantidadeAlunos * sizeof(struct RegistroAluno));
    if (P1 == NULL) {
        printf("Erro ao alocar memória!\n");
        return 1;
    }

    for(int i=0; i<QuantidadeAlunos; i++){
        printf("--- Aluno %d ---\n", i+1);
        
        printf("Qual a matrícula do aluno?\n");
        scanf("%i", &P1[i].Matricula);
        getchar(); // 清除缓冲区换行

        printf("Qual o nome do aluno?\n");
        // 用fgets读取带空格的名字,避免scanf("%s")截断空格
        fgets(P1[i].Nome, sizeof(P1[i].Nome), stdin);
        // 去掉fgets读取到的末尾换行符
        char *newline = strchr(P1[i].Nome, '\n');
        if (newline != NULL) {
            *newline = '\0';
        }

        printf("Qual o ano de nascimento do aluno?\n");
        scanf("%i", &P1[i].AnoNascimento);
        getchar(); // 清除缓冲区换行
    }

    // 示例:打印所有学生信息
    printf("\n--- Lista de Alunos ---\n");
    for(int i=0; i<QuantidadeAlunos; i++){
        printf("Aluno %d:\n", i+1);
        printf("Matrícula: %d\n", P1[i].Matricula);
        printf("Nome: %s\n", P1[i].Nome);
        printf("Ano de Nascimento: %d\n", P1[i].AnoNascimento);
    }

    // 释放动态内存,避免泄漏
    free(P1);
    P1 = NULL; // 避免野指针

    return 0;
}

补充说明

  • 缓冲区处理:scanf("%i")读取整数后,输入的换行符会留在缓冲区,后续用fgets()读取名字时会直接读取空行,所以每次scanf后需要用getchar()清除换行。
  • 名字读取:scanf("%s")只能读取到第一个空格,无法处理带空格的名字,fgets()可以读取整行输入,之后手动截断末尾的换行符即可。
  • 内存释放:动态分配的内存不会自动回收,必须在使用完毕后调用free(),这在长期运行的程序中尤为重要。

内容的提问来源于stack exchange,提问作者Bruna Naian Moreira Lima Garci

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 16:40:27