-1

I'm working on a program that uses a structure with 2d array as fields. But for some reason evrytime I try to use the free_planet function I receive a double free error. Using programs as valgrind it seems the problems are the instructions from row 49 to 51 but I really can't get why.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
typedef enum cell { SHARK, FISH, WATER } cell_t;

typedef struct planet {
    unsigned int nrow; 
    unsigned int ncol; 
    cell_t ** w;
    int ** btime;
    int ** dtime;
} planet_t;


planet_t * new_planet (unsigned int nrow, unsigned int ncol) {
    if ((int) nrow>=0 && (int) ncol>=0){
        int i,j;
        planet_t *a=malloc(sizeof(planet_t*)); 
        a->nrow=nrow;
        a->ncol=ncol;

        a->w=(cell_t**) malloc(nrow * sizeof(cell_t*));
        a->btime=(int**) malloc(nrow* sizeof(int*));
        a->dtime=(int**) malloc(nrow* sizeof(int*));

        for (i=0; i<nrow; i++){
            a->w[i]=(cell_t*) malloc(ncol * sizeof(cell_t));
            a->btime[i]=(int*) malloc(ncol*sizeof(int));
            a->dtime[i]=(int*) malloc(ncol*sizeof(int));
        }

        for (i=0; i<nrow; i++)
            for (j=0; j<ncol; j++)
                a->w[i][j]=WATER;
        return a;
    }
    errno=EINVAL;
    return NULL;
}

void free_planet (planet_t* p){
    int i;
    int nrow=p->nrow;   
    for (i=0;i<nrow;i++){
        if (p->w[i]!=NULL) free (p->w[i]);  
        if (p->btime[i]!=NULL) free (p->btime[i]);
        if (p->dtime[i]!=NULL) free (p->dtime[i]);
    }
    if (p->w!=NULL) free (p->w);
    if (p->btime!=NULL) free (p->btime);
    if (p->dtime!=NULL) free (p->dtime);
    if (p!=NULL) free (p);
    return;
}

int main(){
    planet_t *p; unsigned int x,y;

    scanf( "%u %u", &x, &y);
    p = new_planet(x,y);
    free_planet (p);
    return 0;
}
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
IXion
  • 11
  • 2
  • code? we cannot guess what you wrote at lines 49 and 51! – 23ars Mar 22 '15 at 20:50
  • Yeah sorry I'm posting this from my phone and having some problems doing it :/ – IXion Mar 22 '15 at 20:51
  • 1
    All your tests for `NULL` are pointless since you never initialized anything to `NULL`. – David Heffernan Mar 22 '15 at 20:52
  • @IXion: `free(NULL);` is explicitly valid. So you don't need to worry about the `if NULL` checks if all you're doing is passing the pointer to `free()`. – Bill Lynch Mar 22 '15 at 20:54
  • 1
    You should allocate `planet_t *a=malloc(sizeof(planet_t));` or, maybe better, `planet_t *a=malloc(sizeof(*a));` when you create the planet. – M Oehm Mar 22 '15 at 20:56
  • You're right but even deleting all those checks the problem persist – IXion Mar 22 '15 at 21:00
  • @M Oehm : thanks I've been searching for the problem for the entire day! That solved the problem! – IXion Mar 22 '15 at 21:03
  • The casts on `if ((int) nrow>=0 && (int) ncol>=0){` are a mistake, get rid of them (in fact get rid of the whole line as it is redundant) – M.M Mar 22 '15 at 21:12

1 Answers1

1

Here's the first thing that I see:

planet_t *a = malloc(sizeof(planet_t*)); 

You're allocating space for a pointer when you should be allocating space for the struct. So it should be:

planet_t *a = malloc(sizeof(planet_t)); 

Or:

planet_t *a = malloc(sizeof(*a)); 
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173