Andrew asdf
Andrew asdf

Reputation: 21

Why am I getting the Segmentation fault (core dumped) error in my program when using 2d arrays?

I'm attempting to create Conway's Game of Life in c++ (https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life) and I have no idea as to why it throws this error. Here is my code:

#include <iostream>

using namespace std;
void Life() {
    //initializing all the variables needed
    int creatures;
    int row;
    int column;
    int neighbors = 0;
    int days = 0;
    char cont = 'c';
    //creates Board
    string Board[20][20];
    string NewBoard[20][20];
    //stores X for dead into all elements
    for (int r = 0; r <= 19; r++) {
        for (int c = 0; c <= 19; c++) {
            Board[r][c] = "X ";
        }
    }
    //asks for and stores the users coords
    cout<<"Enter the amount of creatures desired: ";
    cin>>creatures;
        for (int i = 0; i <= creatures - 1; i++) {
            cout<<"\nEnter the row of the next creature: ";
            cin>>row;
            cout<<"\nEnter the column of the next creature: ";
            cin>>column;
            Board[row - 1][column - 1] = "O ";
        }
    for (int r = 0; r <= 19; r++) {
        for (int c = 0; c <= 19; c++) {
            NewBoard[r][c] = Board[r][c];
        }
    }

    while (cont == 'c') {
        for (int r = 0; r <= 19; r++) {
            for (int c = 0; c <= 19; c++) {
                Board[r][c] = NewBoard[r][c];
            }
        }
        cout<<"\n\n\n\nDay "<<days<<"\n";
        //prints current board
        for (int r = 0; r <= 19; r++) {
            cout<<"\n";
            for (int c = 0; c <= 19; c++) {
                cout<<Board[r][c];
        }
    }
        cout<<"\n\n";
        //detects for alive creatures then checks them for neighbors
        for (int r = 0; r <= 19; r++) {

            for (int c = 0; c <= 19; c++) {
                //detects for life
                if (Board[r][c] == "O ") {
                    //detects for neighbors
                    neighbors = 0;
                    if (Board[r + 1][c + 1] == "O ") {
                        neighbors++;
                    }
                    if (Board[r + 1][c] == "O ") {
                        neighbors++;
                    }
                    if (Board[r + 1][c - 1] == "O ") {
                        neighbors++;
                    }
                    if (Board[r][c + 1] == "O ") {
                        neighbors++;
                    }
                    if (Board[r][c - 1] == "O ") {
                        neighbors++;
                    }
                    if (Board[r - 1][c + 1] == "O ") {
                        neighbors++;
                    }
                    if (Board[r - 1][c] == "O ") {
                        neighbors++;
                    }
                    if (Board[r - 1][c - 1] == "O ") {
                        neighbors++;
                    }
                    //kills the creature if it has less than 2 or more than 3 living neighbors
                    if (neighbors < 2) {
                        NewBoard[r][c] = "X ";
                    }
                }
                //if creature is dead, checks to see how many live neighbors
                else {
                    neighbors = 0;
                    if (Board[r + 1][c + 1] == "O ") {
                        neighbors++;
                    }
                    if (Board[r + 1][c] == "O ") {
                        neighbors++;
                    }
                    if (Board[r + 1][c - 1] == "O ") {
                        neighbors++;
                    }
                    if (Board[r][c + 1] == "O ") {
                        neighbors++;
                    }
                    if (Board[r][c - 1] == "O ") {
                        neighbors++;
                    }
                    if (Board[r - 1][c + 1] == "O ") {
                        neighbors++;
                    }
                    if (Board[r - 1][c] == "O ") {
                        neighbors++;
                    }
                    if (Board[r - 1][c - 1] == "O ") {
                        neighbors++;
                    }
                    //"resurrects" creature if it has 3 neighbors
                    if (neighbors == 3) {
                        NewBoard[r][c] = "O ";
                    }
                }
            }
        }
        //asks if user wants to continue
        cout<<"\n\nPress c to continue, q to quit: ";
        cin>>cont;
        days++;
    }
}

int main()
{
    Life();
    return 0;
}

Sorry if it's really hard to read (I'm still learning). I've concluded that the problem comes from the else part of the while loop. Why is this?

Upvotes: 1

Views: 55

Answers (1)

Sam Varshavchik
Sam Varshavchik

Reputation: 118292

    for (int r = 0; r <= 19; r++) {
        for (int c = 0; c <= 19; c++) {

Inside this loop you will have both r and c cover the entire range of 0-19.

                if (Board[r + 1][c + 1] == "O ") {
                    neighbors++;
                }

When either r or c is 19, here, this is going to attempt to access either Board[20][something] or Board[something][20], which, of course, does not exist. Undefined behavior. Crash.

                if (Board[r - 1][c - 1] == "O ") {
                    neighbors++;
                }

Similarly, when either r or c is 0, this will attempt to access a negative array index. Undefined behavior. Crash.

The above are just an example of a common defect that nearly all of your if statements suffer: lack of proper bounds checking.

Upvotes: 4

Related Questions