Search code examples
cmatrixsegmentation-faultfree

Segmentation fault after a free()


I'm trying to dynamically allocate one matrix N*N and put random numbers (between 0 and h-1) in it. I also have to create a function that deallocates it. The problem is that I have to use structures and I'm not very used to them. Structure "game_t" is defined in another file and included.

game_t * newgame( int n, int m, int t){
    game_t x, *p;
    int i,j;
    p=&x;
    x.t=t;
    x.n=n;    /* structure game has n,t,h,board as keys*/
    x.h=h;
    srand(time(NULL)); 
    x.board=malloc(n*sizeof(int*));    /*Allocate*/
    if (x.board==NULL) return NULL;
    for (i=0;i<n;i++){
              x.board[i]=malloc(n*sizeof(int));}
    for (i=0;i<n;i++){   /*put random numbers*/
             for (j=0;i<n;j++){
                     x.board[i][j]=rand()%h;}}
    return p;
}

void destroy(game_t *p){
    int i;
    for (i=0;i<p->n;i++){
        free(p->board[i]);}
    free(p->board);
}

Solution

  • You return the pointer to the local variable x. Local variables disappear once you leave their scope.

    game_t * newgame( int n, int m, int t){
        game_t x, *p;
        int i,j;
        p=&x;    // <<<< p points to the local variable x
        x.t=t;
        x.n=n;
        x.h=h;
        srand(time(NULL)); 
        x.board=malloc(n*sizeof(int*));
        if (x.board==NULL) return NULL;
        for (i=0;i<n;i++){
                  x.board[i]=malloc(n*sizeof(int));}
        for (i=0;i<n;i++){
                 for (j=0;i<n;j++){
                         x.board[i][j]=rand()%h;}}
        return p;
    }
    

    You probably want this:

    game_t * newgame( int n, int m, int t){
        game_t *p = malloc(sizeof (*p));   // allocate memory for a new game_t
        int i,j;
        p->t=t;
        p->n=n;
        p->h=h;
        srand(time(NULL)); 
        p->board=malloc(n*sizeof(int*));
        if (p->board==NULL) return NULL;
        for (i=0;i<n;i++){
                  p->board[i]=malloc(n*sizeof(int));}
        for (i=0;i<n;i++){
                 for (j=0;i<n;j++){
                         p->board[i][j]=rand()%h;}}
        return p;
    }
    

    BTW: you should use meaningful variable names. For example p should be named new etc.

    Bonus: call srand(time(NULL)) only once at the start of the program.