1

I'm writing the minesweeper game in C. I want be able to play games with different minefields with different sizes and number of mines I've created such structures to describe my data:

typedef struct t_Place Place;

struct t_Place{
    unsigned numberOfMinesNear;
    int mine;
    int state;
};

typedef struct t_Minefield Minefield;

struct t_Minefield{
    int xSize;
    int ySize;
    unsigned minesNumber;
    Place **places; 
};

So, now I'm trying to initialize my minefield. I do the following:

void makeGame(Minefield *minefield, unsigned x, unsigned y, unsigned mines){
    int i, j;  
minefield->places = malloc(x * y * sizeof(Place));       
    for(i = 0; i < x; i++)
        for(j = 0; j < y; j++){
            minefield->places[i][j].mine = EMPTY;
            minefield->places[i][j].state = HIDDEN;
            minefield->places[i][j].numberOfMinesNear = 0;
        }

minefield->xSize = x;
    minefield->ySize = y;

    unsigned minesToPlace = mines;
    srand(time(NULL));
    while(minesToPlace > 0){
        i = rand() % x;
        j = rand() % y;

        if(minefield->places[i][j].mine)
            continue;

        minefield->places[i][j].mine = MINE;
        minesToPlace--;      
    }  
    minefield->minesNumber = mines;
    // here will be call of play(minefield) function to start the game
}

int main(){
    Minefield *gameField = (Minefield *) malloc(sizeof(Minefield));

    makeGame(gameField, DEFAULT_X, DEFAULT_Y, DEFAULT_MINES);

    // DEFAULT_X = DEFAULT_Y = DEFAULT_MINES =  10

    free(gameField);
    return 0;
}

I'm getting segfault at first line of code in makeGame function. What i'm doing wrong? I want allocate memory for my minefield dynamically, not statically.

Ilya Boltnev
  • 1,031
  • 3
  • 13
  • 27
  • The code you have shown doesn't produce an seg-fault. edit and add more code to get an answer – Grijesh Chauhan Mar 15 '13 at 17:38
  • Seconded, works fine here. Also you should free minefield->places as well. – Andrew T Mar 15 '13 at 17:41
  • added some code in makeGame() procedure – Ilya Boltnev Mar 15 '13 at 17:47
  • the only way that first line can fail is is the minefield pointer itself is wrong (or your heap is trashed). What does the debugger say? – pm100 Mar 15 '13 at 17:51
  • gdb says: `Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000004` when i'm trying to access minefield->places – Ilya Boltnev Mar 15 '13 at 17:53
  • 1
    I started to think that cause my fail is in wrong allocation multidimensional array http://www.eskimo.com/~scs/cclass/int/sx9b.html – Ilya Boltnev Mar 15 '13 at 17:55
  • It's good form to check if your malloc returns something besides NULL. Also, if you just want to move on, create a static array for your minefield of the largest field size and only use that part of it that you need. – Michael Dorgan Mar 15 '13 at 18:13

2 Answers2

2
minefield->places = malloc(x * y * sizeof(Place)); 

The above memory allocation might be the source of the problem , places is a two star pointer , so there must be two malloc() calls , one to allocate the row number **place pointers , and then another malloc() , to allocate column number of *place pointers of type place.

Here is a SSCCE of allocating/initializing a two star pointer contained inside a structure.

#include <stdio.h>
#include <stdlib.h>

#define ROW_SZ 5
#define COL_SZ 25

typedef struct demo{
char **str;
}demo;


int main()
{

demo *d = malloc( sizeof(demo) );

d->str = malloc(ROW_SZ * sizeof(char*) );             //d->str is assigned char**
  for ( i = 0; i < ROW_SZ; i++ )
        d->str[i] = malloc(COL_SZ * sizeof(char) );   //d-str[i] is assigned char*

// code here to use d->str[ROW_SZ][COL_SZ]

for ( i = 0; i < ROW_SZ; i++ )
  free(d->str[i]);


free(d->str);
free(d);

return 0;
}
Barath Ravikumar
  • 5,658
  • 3
  • 23
  • 39
1

This is how I usually see 2D arrays allocated:

minefield->places = malloc(x * sizeof(Place *));       

for(i = 0; i < x; i++)
{
    minefield->places[i] = malloc(x * sizeof(Place));
}

Try this and see if it makes you segfault vanish.

Michael Dorgan
  • 12,453
  • 3
  • 31
  • 61