在函数中初始化的结构丢失值虽然它是一个数组

问题描述

我正在尝试在“leggif1”中初始化数组 *dip,在里面如果你打印它是正常的,但是如果你尝试在 main 中打印,在初始化之后,一切都会丢失它的值。 同样的事情发生在一年级“Divisione”的 ADT 上,我不明白为什么(即使由于它们的指针,它们是“通过引用”传递的)。

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

typedef struct {
  int matricola;
  char nome[20+1],cognome[20+1];
  int comp[4];            
}dipendente;

typedef struct divisione  *Divisione;
struct divisione{
dipendente *dip;
char nome[10+1];
int terna[4][3];        //numero minimo di addetti,competenza minima totale,competenza ottimale totale
                        //per ognuna delle 4 tipologie
};

void leggif1(dipendente *dip,char *filename);
int leggif2(Divisione *Div,char *filename);
void DIvstampa(Divisione *Div,char *filename,int D);
Divisione DIVinit();
void DIVfree(Divisione *Div);

int main(int argc,char **argv) {
dipendente *dip;
Divisione *Div;
leggif1(dip,argv[1]);
int D=leggif2(Div,argv[2]);
DIvstampa(Div,"stdout",D);

return 0;
}

void leggif1(dipendente *dip,char *filename) {
FILE *fp=fopen(filename,"r");
int i,N;

fscanf(fp,"%d",&N);
dip=malloc(N*sizeof(dipendente));

for(i=0;i<N;i++)
    fscanf(fp,"%d %s %s %d %d %d %d",&dip[i].matricola,dip[i].nome,dip[i].cognome,&dip[i].comp[0],&dip[i].comp[1],&dip[i].comp[2],&dip[i].comp[3]);

}

int leggif2(Divisione *Div,j,D;
fscanf(fp,&D);
Div=malloc(D*sizeof(Divisione));
for(i=0;i<D;i++)
    Div[i]=DIVinit();

for(i=0;i<D;i++) {
    fscanf(fp,"%s",Div[i]->nome);
    for (j = 0; j < 4; j++)
        fscanf(fp,"%d %d %d",&Div[i]->terna[j][0],&Div[i]->terna[j][1],&Div[i]->terna[j][2]);
}

return D;
}

void DIvstampa(Divisione *Div,int D) {
FILE *fp;
if(strcmp(filename,"stdout")==0)
    fp=stdout;
else
    fp=fopen(filename,"w");

int i,j;
for(i=0;i<D;i++) {
    fprintf(fp,"%s\n",Div[i]->nome);
    for(j=0;j<4;j++)
        fprintf(fp,"%d %d %d\n",Div[i]->terna[j][0],Div[i]->terna[j][1],Div[i]->terna[j][2]);
}

}
Divisione DIVinit(){
Divisione Div=malloc(sizeof (*Div));
return Div;
}

void DIVfree(Divisione *Div){
free(Div);
}

解决方法

leggif1 函数会忽略 dip 的值并为其分配一个新值。该值永远不会返回到 main。

dip 的类型是 dipendente*,当在 main 中调用时,指针的值被传递给函数。覆盖函数中的本地副本不会影响 main 中指针的值。

C 只有“按值调用”,请始终确保您知道该值代表什么。

这可以通过返回函数中的dip而不是将其作为参数来解决:

dipendente* leggif1(char *filename)
{
    //open file and read N
    dipendente *dip = malloc(N * sizeof *dip);
    if (!dip) {
        return NULL;
    }
    // read in the data

    return dip;
}

另一种方法是使用 dipendente**(指向指针的指针),但在这种情况下,这会使代码变得不必要地复杂。

leggif2 函数也有同样的问题。