如何解决错误进程在C中返回-1073741819

时间:2015-04-25 09:34:52

标签: c memory minesweeper

这将是一个扫雷但尚未完成。目前,该程序应该询问您阵列的大小和地雷数量。然后,它显示隐藏的板(带有数字和X'作为地雷的板)。这就是全部。

问题是程序停止使用此错误

  

进程返回-1073741819< 0xC0000005>

我认为这是一个记忆问题,但我不知道问题出在哪里。

很抱歉,因为评论是西班牙语。我会尝试添加一些大写字母以使其可以理解。代码:

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);
}

1 个答案:

答案 0 :(得分:0)

当您确定何时处于右边界或下边界时,您只有一次:

if (j == y)

这不可能,因为它发生在条件为j < y的循环中。永远不会输入右边和右边边框情况,您最终会访问j + 1i + 1处的字段,这是数组之外的一个条目。

您根本不需要区分这些案例。大小写确定要扫描的邻近区域的边界,但是您可以通过简单的计算来完成,然后在边界上调整范围:

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

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

同样适用于i。这将消除大量重复的代码。