I'd like to extend my array containing a struct 'Article' using realloc, so I tell realloc to take the old array and extend it then I add my new Article to the new array but this doesn't work and i can't find the problem. this is the error message >corrupted size vs. prev_size Abandon (core dumped)
typedef struct
{
char ref[6];
float pu;
int qt;
char desi[31];
}Article;
void global(void)
{
FILE * fe;
Article *tart,l;
int nbart;
fe=fopen("a.txt","a ");
tart=chargeFarticle(fe,&nbart);
Showtart(tart,nbart);
printf("Ref: ");
scanf("%s",l.ref);
printf("pu: ");
scanf("%f",&l.pu);
printf("qt: ");
scanf("%d%*c",&l.qt);
printf("Desi: ");
fgets(l.desi,31,stdin);
l.desi[strlen(l.desi) -1]='\0';
tart=AddArt(l,tart,&nbart);
Showtart(tart,nbart);
fclose(fe);
}
Article readArt(FILE * fe)
{
Article a;
fscanf(fe,"%s%f%d",a.ref,&a.pu,&a.qt);
fgets(a.desi,31,fe);
a.desi[strlen(a.desi) - 1]='\0';
return a;
}
Article * chargeFarticle(FILE*fe,int *nbart)
{
Article *tart;
int i;
fscanf(fe,"%d",nbart);
tart=(Article *)malloc(*nbart*sizeof(Article));
if(tart==NULL)
{
printf("Pb Malloc\n");
exit(1);
}
for(i=0;i<*nbart;i )
tart[i]=readArt(fe);
return tart;
}
Article * AddArt(Article l,Article *tart,int *nbart)
{
int i;
Article *aux;
aux=(Article *)realloc(tart,*nbart*sizeof(Article));
free(tart);
tart=aux;
tart[*nbart]=l;
*nbart =1;
return tart;
}
CodePudding user response:
At least these problems:
Bad free()
When realloc()
works, not need to free(old pointer)
. In fact, realloc()
may return the same pointer.
aux=(Article *)realloc(tart,*nbart*sizeof(Article));
// free(tart);
Better to test for allocation success and drop the unnecessary casts.
if (*nbart < 0) {
// Handle error
}
aux = realloc(tart,sizeof *tart * *nbart);
if (aus == NULL && *nbart > 0) {
// Handle error
}
Out of range
tart[*nbart]=l;
accesses tart[*nbart]
out of its range.
Unsafe zeroing
l.desi[strlen(l.desi) -1]='\0';
does not certainly lop of the trailing '\n'
. '\n'
might not exist, fgets()
may have failed, with nefarious input strlen(l.desi)
may be 0.
Better as l.desi[strcspn(l.desi, "\n")] = '\0'
Other issues?
CodePudding user response:
a.desi[strlen(a.desi) - 1]='\0';
char *removeNewLine(char *c)
{
char *wrk = c;
if(c)
{
while(*wrk) wrk ;
if(wrk - c)
{
if(wrk[-1] == '\n') wrk[-1] = 0;
}
}
return c;
}
Many other errors - listed by @chux.
I would implement is other way:
typedef struct
{
char ref[6];
float pu;
int qt;
char desi[31];
}Article;
typedef struct
{
size_t nArticles;
Article articles[];
}Articles_db;
Articles_db *readArt(Articles_db *art, FILE *fe)
{
size_t newsize = art ? art -> nArticles 1 : 1;
art = realloc(art, sizeof(*art) sizeof(art -> articles[0]) * newsize);
if(art)
{
Article *a = art -> articles newsize - 1;
fscanf(fe,"%s%f%d", a -> ref, &a -> pu, &a -> qt);
fgets(a -> desi,31,fe);
/* check the results of the I/O functions */
art -> nArticles = newsize;
}
return art;
}
Articles_db *chargeFarticle(FILE*fe,int *nbart)
{
Articles_db *tart = NULL, *tmp;
int i;
fscanf(fe,"%d",nbart);
/* check the result of fscanf */
for(i=0;i<*nbart;i )
{
tmp = readArt(tart, fe);
if(!tmp)
{
printf("Memory allocation error\n");
break;
}
tart = tmp;
}
return tart;
}