指针等等 [C]

Pointers and all that [C]

好吧,我正在尝试创建一个简单的程序来打印学生列表的名称,问题是,我做了所有需要的事情,但是当我尝试打印所有元素时,结果是一样的.它是葡萄牙语,但我认为这应该不是问题。

程序如下:

#include <stdlib.h>
#include <stdio.h>

typedef struct struct_t{

   char * nome;
   int * notas; 


}DADOS_ALUNOS;

typedef struct struct_s{

    DADOS_ALUNOS total_alunos;


}ALUNOS;

int main (){

         
    ALUNOS * Classe;
    DADOS_ALUNOS aluno;
    int numero_alunos, quantidade_provas, i;


    printf("Digite a quantidade de alunos\n");
    scanf("%d", &numero_alunos);
    printf("Agora, digite a quantidade de provas dadas\n");
    scanf("%d", &quantidade_provas);

    printf ("Total numeoro alunos: %d\n", numero_alunos);

    Classe = (ALUNOS *) malloc (numero_alunos * sizeof(ALUNOS));
    aluno.nome = (char *) malloc (sizeof(char) * 20);
    
    for (i = 0; i < numero_alunos; i++){

        printf("Digite o nome do aluno\n");
        scanf("%s", aluno.nome);

       //printf("O que está contindo na variavael temporaria: %s", aluno.nome);
        
        Classe[i].total_alunos.nome = (char *) malloc (sizeof(aluno.nome));
        Classe[i].total_alunos.nome = aluno.nome;
        //printf("O que está contindo na variavael : %s", Classe[i].total_alunos.nome);
        //free(aluno.nome);

    }

    for (i = 0; i < numero_alunos; i++){

        printf("Nome: %s\n", Classe[i].total_alunos.nome);

    }



    return 0;
}

欢迎提出任何建议。

在这些陈述中:

    Classe[i].total_alunos.nome = (char *) malloc (sizeof(aluno.nome));
    Classe[i].total_alunos.nome = aluno.nome;

产生了内存泄漏。

首先分配内存并将其地址分配给指针Classe[i].total_alunos.nome然后将指针重新分配为for循环之前分配的内存地址:

    Classe[i].total_alunos.nome = aluno.nome;

至少你需要像这样使用字符串函数strcpy

    strcpy( Classe[i].total_alunos.nome, aluno.nome );

前提是你为指针Classe[i].total_alunos.nome指向的数组分配了足够的space因为在这个分配中

Classe[i].total_alunos.nome = (char *) malloc (sizeof(aluno.nome));

你只为指针分配内存。即 sizeof(aluno.nome ) 等于 sizeof( char * ).

不过注意还是会出现内存泄漏,因为指针aluno.nome指向的内存没有被释放

声明类型为 DADOS_ALUNOS:

的对象没有多大意义
DADOS_ALUNOS aluno;

然后动态分配内存:

aluno.nome = (char *) malloc (sizeof(char) * 20);

相反,您可以只声明一个字符数组,例如:

char nome[20];

并在 for 循环中使用此数组:

scanf( " %19[^\n]", nome );
       ^^^^^^^^^^  

几个问题。

首先,改变

Classe[i].total_alunos.nome = (char *) malloc (sizeof(aluno.nome));

Classe[i].total_alunos.nome = malloc( strlen( aluno.nome ) + 1 );

从 C89 开始,malloc 上的强制转换是不必要的,并且在 C89 标准下可以抑制有用的诊断。

表达式 aluno.nome 的类型是 char *,因此 sizeof( aluno.nome ) 给出 指针的大小 ,而不是 的大小它指向的缓冲区。使用strlen获取输入字符串的长度,然后加1作为终止符。

接下来,改变

Classe[i].total_alunos.nome = aluno.nome;

strcpy( Classe[i].total_alunos.nome, aluno.nome );

= 运算符未定义为将一个数组的内容复制到另一个数组 - 为此,您必须使用 strcpymemcpy 等库函数,或在循环中单独复制元素。您在这里所做的就是将存储在 aluno.nome 中的指针值分配给 Classe[i].total_alunos.nome,并且在此过程中您将丢失对您使用 malloc 分配的内存的引用,从而导致内存泄漏。

最后,不要使用 scanf 来读取字符串输入,而是使用 fgets - 它可以更容易地防止缓冲区溢出:

printf("Digite o nome do aluno\n");
fgets( aluno.nome, 20, stdin );

这会将最多 19 个字符读入 aluno.nome 并终止字符串。您也可以使用 scanf 来做到这一点:

scanf( "%19s", aluno.nome );

但必须在转换说明符中对长度进行硬编码;您不能像使用 printf.

那样使用 * 在运行时指定长度