简体   繁体   中英

Struct initialized in function loses values (although it's an array)

I'm trying to initialize array *dip inside "leggif1", inside it if you do a print it's all normal but if you try to print in the main, after the initialization, everything loses its values. Same thing happen with ADT of first grade "Divisione" and i can't understand why (even though they are passed "by reference" thanks to their pointers).

#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, char *filename) {
FILE *fp=fopen(filename,"r");
int i,j,D;
fscanf(fp,"%d",&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, char *filename, 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);
}

The leggif1 function ignores the value of dip and assigns it a new value. That value is never returned to main.

The type of dip is dipendente* and when called in main the value of the pointer is passed to the function. Overwriting that local copy in the function does not affect the value of the pointer in main .

C only has 'call by value', always make sure you known what that value represents.

This can be solved by returning the dip from the function instead of taking it as a parameter:

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

another way is to use a dipendente** (a pointer to a pointer) but that would, in this case, make the code needlessly complex.

The leggif2 function has the same problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM