将结构体的指针保存到指针数组中

时间:2019-05-11 21:41:25

标签: c pointers struct

我很难获取指向结构的指针数组以保存和检索填充的数据,代码段是程序的核心。

我能够使用结构数组来使程序本身运行,但是我认为这会占用更多的内存,因此我试图仅将指针数组重新分配给结构,而不是在每个循环中重新分配所有结构。 / p>

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

typedef struct dados_aluno {
    int matricula;
    char nome[60];
    int situacao;
    float nota1, nota2, nota3, media;
}dados_aluno;

int main(void){
    int done = 0;
    int i;
    int n_alunos = 0;
    int matricula_atual;

    dados_aluno *novo_aluno;
    dados_aluno **alunos_da_turma;
    alunos_da_turma = malloc(sizeof(dados_aluno*));
    while (done == 0){
        printf("Matricula: ");
        scanf("%d", &matricula_atual);
        fflush(stdin);//scanf followed by gets = bad time!
        if (matricula_atual == -1){
            done = 1;
            continue;
        }
        n_alunos++;
        novo_aluno = calloc(1, sizeof(dados_aluno));
        novo_aluno->matricula = matricula_atual;

        printf("\nNome: ");
        gets(novo_aluno->nome);

        //the code below rises warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
        //and returns garbage on the for loop at the end of the program
        alunos_da_turma[n_alunos - 1] = &novo_aluno;
        //using memcpy instead doesnt rise an error, but the first field is garbage and the 3º interation of the loop crashes
        //memcpy(alunos_da_turma[n_alunos -1],&novo_aluno,sizeof(dados_aluno *));
        alunos_da_turma = realloc(alunos_da_turma, (sizeof(dados_aluno *) * (n_alunos + 1)));
    }
    for (i=0;i<(n_alunos);i++){
            printf("%d  %s\n",alunos_da_turma[i]->matricula,alunos_da_turma[i]->nome);
    }
}

我希望动态分配一个结构“ dados_alunos”,并动态分配一个指向所述结构的指针数组,将用户输入“ nome”和“ matricula_atual”插入结构“ dados_alunos”的字段中并能够读取它们退出while循环后。 尝试使用以下方法将地址保存到当前结构的数组中时

alunos_da_turma[n_alunos - 1] = &novo_aluno;

发出警告“来自不兼容指针类型[-Wincompatible-pointer-types]的赋值”,并且似乎无论写入多少次,都会将写入其的第一个指针/垃圾保存到数组的所有位置。 如果我只尝试一次交互并在while循环中两次或更多次崩溃,则使用memcpy代替将垃圾存储在第一个字段上。

2 个答案:

答案 0 :(得分:2)

alunos_da_turma[n_alunos - 1] = &novo_aluno;

之所以被拒绝是因为alunos_da_turmadados_aluno **,所以alunos_da_turma[n_alunos - 1]dados_aluno *,而novo_alunodados_aluno *,所以{{1} }是&novo_aluno

您想要的

dados_aluno **

警告

alunos_da_turma[n_alunos - 1] = novo_aluno;

是危险的(并且自多年以来不推荐使用),因为如果输入字符串大于59个字符,则您以意外的行为写出了字段,请这样做

gets(novo_aluno->nome);

但是,如果您在同一行中输入名称,那么您将得到一个空行,因为该行/换行符的其余部分不会被fgets(novo_aluno->nome, sizeof(novo_aluno->nome), stdin); fflush 刷新无法在文件中工作

如果名称不能包含分隔符,请使用fflush(stdin);而不是 fgets ,否则,请明确地将字符绕到换行符

也请注意

scanf("%59s", novo_aluno->nome);

您使用一个额外的元素重新分配,您已经增加了alunos_da_turma = realloc(alunos_da_turma, (sizeof(dados_aluno *) * (n_alunos + 1)));

n_alunos

很复杂,什么都没有,可以替换为

int done = 0;
...
while (done == 0){
    ...
    if (matricula_atual == -1){
        done = 1;
        continue;
    }
    ...
}

答案 1 :(得分:1)

alunos_da_turma[X]是指向结构dados_aluno的指针,而不是指向结构dados_aluno的指针。 有效的是alunos_da_turma[n_alunos-1] = novo_aluno

因此,一些解决一般问题的方法:

dados_alunos** alunos_da_turma = malloc (10 * sizeof(dados_aluno*)); //array for 10 pointers
int length = 0;  //number of inserted alunos_dados elements
int size = 10;  //number of allocated pointers spaces
while(done == 0){
//ask for input
    dados_aluno* novo_aluno = malloc (sizeof(dados_aluno));
    novo_aluno->matricula = //input
    //etc
    dados_alunos[length] = novo_aluno;
    length++;
    if (length == size){
         dados_alunos = realloc(dados_alunos, 2 * size * sizeof(dados_aluno*));
         size += size; //doubles size
    }
}