-4

This is going to be a Minesweeper but is not finished yet. For now, the program should ask you for the size of the array and the number of mines. Then, it shows the hidden board (the one with numbers and 'X' as mines). That's all.

The problem is that the program stop working with this error

process returned -1073741819 <0xC0000005>

I think it's a memory problem, but I don't know where the problem is.

Sorry, because the comments are in Spanish. I'll try to add some in capital letters to make it understandable. The code:

main.c

#include <stdio.h>
#include <stdlib.h>
#include "Tablero/tablero.h"
#include <stdbool.h>

int main()
{
    int fils, cols, nMinas; //ROWS, COLUMNS, NUMBER OF MINES
    printf("Introduzca el número de filas: ");
    scanf("%d", &fils);
    printf("Introduzca el número de columna: ");
    scanf("%d", &cols);
    printf("Introduzca el número de minas: ");
    scanf("%d", &nMinas);

    Tablero tab = crearTablero(fils, cols, nMinas);//CREATE BOARD
    mostrarTablero(tab.tabOculto, tab.x, tab.y);//SHOW HIDDEN BOARD

    liberarTablero(tab);//FREE THE MEMORY

    return 0;
}

tablero.h

#ifndef TABLERO_H_INCLUDED
#define TABLERO_H_INCLUDED

typedef struct{
    int x;//ROWS
    int y;//COLUMNS
    int numMinas;//NUMBER OF MINES
    char **tabOculto;//HIDDEN BOARD
    char **tabVisible;//VISIBLE BOARD
} Tablero;

Tablero crearTablero(int x, int y, int numMinas);//CREATE BOARD

void mostrarTablero(char **tab, int x, int y);//SHOW BOARD

void liberarTablero(Tablero tab);//FREE BOARD

#endif // TABLERO_H_INCLUDED

tablero.c

#include "tablero.h"
#include <stdio.h>
#include<stdlib.h>
#include<time.h>

//CREATE BOARD
Tablero crearTablero(int x, int y, int numMinas){
    Tablero tab;

    tab.x = x;//ROWS
    tab.y = y;//COLUMNS
    tab.numMinas = numMinas;//NUMBER OF MINES
    int i, j, k, l;

    //Iniciamos y establecemos el contenido del tablero que se va a ver por consola
    //INITIATE AND ESTABLISH THE CONTENT OF THE VISIBLE BOARD
    tab.tabVisible = (char**) malloc (x * sizeof(char*));
    for(i = 0; i < x; i++)
        tab.tabVisible[i] = (char*) malloc (y * sizeof(char));
    //Rellenamos con asteriscos para marcar la casilla normal
    for(i = 0; i < x; i++)
        for(j = 0; j < y; j++)
            tab.tabVisible[i][j] = '*';

    //Iniciamos y establecemos el contenido del tablero oculto, que se irá identificando
    //INITIATE AND ESTABLISH THE CONTENT OF THE HIDDEN BOARD
    tab.tabOculto = (char**) malloc (x * sizeof(char*));
    for(i = 0; i < x; i++)
        tab.tabOculto[i] = (char*) malloc (y * sizeof(char));
    //Rellenamos con ceros antes de distribuir minas
    //FIRST, FILL EVERYTHING WITH '0'
    for(i = 0; i < x; i++)
        for(j = 0; j < y; j++)
            tab.tabOculto[i][j] = '0';
    //Introducimos las minas aleatoriamente
    //ESTABLISH RANDOM MINE POSITION
    srand(time(NULL));
    for(i = 0; i < tab.numMinas; i++)
        tab.tabOculto[(int)rand() % x][(int)rand() % y] = 'X';

    //Ponemos los números según las minas que tengan alrededor
    //PUT THE NUMBERS DEPENDING ON THE QUANTITY OF MINES AROUND AND THE POSITION
    for(i = 0; i < x; i++)
        for(j = 0; j < y; j++)
            if(tab.tabOculto[i][j] == 'X'){
                //Esquina superior izquierda: de posx, posy a posx+1, posy+1
                if(i == 0 && j == 0){
                    for(k = i; k <= i+1; k++)
                        for(l = j; l <= j+1; l++)
                            if(tab.tabOculto[k][l] != 'X')
                                tab.tabOculto[k][l]++;
                }
                //Esquina superior derecha: de posx, posy-1 a posx+1, posy
                else if(i == 0 && j == y){
                    for(k = i; k <= i+1; k++)
                        for(l = j-1; l <= j; l++)
                            if(tab.tabOculto[k][l] != 'X')
                                tab.tabOculto[k][l]++;
                }
                //Esquina inferior izquierda: de posx-1, posy a posx, posy+1
                else if(i == x && j == 0){
                    for(k = i-1; k <= i; k++)
                        for(l = j; l <= j+1; l++)
                            if(tab.tabOculto[k][l] != 'X')
                                tab.tabOculto[k][l]++;
                }
                //Esquina inferior derecha: de posx-1, posy-1 a posx, posy
                else if(i == x && j == y){
                    for(k = i-1; k <= i; k++)
                        for(l = j-1; l <= j; l++)
                            if(tab.tabOculto[k][l] != 'X')
                                tab.tabOculto[k][l]++;
                }
                //Borde superior: de posx, posy-1 a posx+1, posy+1
                else if(i == 0){
                    for(k = i; k <= i+1; k++)
                        for(l = j-1; l <= j+1; l++)
                            if(tab.tabOculto[k][l] != 'X')
                                tab.tabOculto[k][l]++;
                }
                //Borde inferior: de posx-1, posy-1 a posx, posy+1
                else if(i == x){
                    for(k = i-1; k <= i; k++)
                        for(l = j-1; l <= j+1; l++)
                            if(tab.tabOculto[k][l] != 'X')
                                tab.tabOculto[k][l]++;
                }
                //Borde izquierdo: de posx-1, posy a posx+1, posy+1
                else if(j == 0){
                    for(k = i-1; k <= i+1; k++)
                        for(l = j; l <= j+1; l++)
                            if(tab.tabOculto[k][l] != 'X')
                                tab.tabOculto[k][l]++;
                }
                //Borde derecho: de posx-1, posy-1 a posx+1, posy
                else if(j == y){
                    for(k = i-1; k <= i+1; k++)
                        for(l = j-1; l <= j; l++)
                            if(tab.tabOculto[k][l] != 'X')
                                tab.tabOculto[k][l]++;
                }
                //Sin borde: de posx-1, posy-1 a posx+1, posy+1
                else{
                    for(k = i-1; k <= i+1; k++)
                        for(l = j-1; l <= j+1; l++)
                            if(tab.tabOculto[k][l] != 'X')
                                tab.tabOculto[k][l]++;
                }
            }
    return tab;
}
//SHOW BOARD
void mostrarTablero(char **tab, int x, int y){
    int i, j;
    for(i = 0; i < x; i++){
        for(j = 0; j < y; j++)
            printf(" %c ", tab[i][j]);
        printf("\n");
    }
}
//FREE BOARD
void liberarTablero(Tablero tab){
    //liberamos la memoria reservada a los arrays
    int i;
    for(i = 0; i < tab.x; i++){
        free(tab.tabOculto[i]);
        free(tab.tabVisible[i]);
    }
    free(tab.tabOculto);
    free(tab.tabVisible);
}
shA.t
  • 16,580
  • 5
  • 54
  • 111
  • 1
    Please generally avoid thanking the people helping you. Also please avoid any kind of "God will be kind to you" sentence. If you have an error message, please try to identify the line/function it's thrown from. – Kyll Apr 25 '15 at 09:41
  • `i < x;`..`k <= i+1`..`tab.tabOculto[k][l]` caused outside array bounds. – BLUEPIXY Apr 25 '15 at 09:57
  • I'll keep that in mind. Still, that was not the problem. – biblic_death Apr 25 '15 at 10:25

1 Answers1

0

You are one off when you determine when you are at the right or bottom borders:

if (j == y)

This can't be true, because it occurs in a loop whose condition is j < y. The right and bottom border cases are never entered and you end up accessing fields at j + 1 and i + 1, which is one entry beyond the array.

You don't need to distinguish between the cases at all. The case determines the bounds of your neighbouring area to scan, but you could do that with a simple calculation and then adjust the range when you are on a border:

int jmin = j - 1;
int jmax = j + 1;

if (j == 0) jmin = 0;
if (jmax == y) jmax = y - 1;

And likewise for i. This will get rid of a lot of repetitive code.

M Oehm
  • 28,726
  • 3
  • 31
  • 42