Home > OS >  Using realloc with a table containing structures
Using realloc with a table containing structures

Time:12-06

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;
}
  •  Tags:  
  • c
  • Related