处理2D数组时的分割故障

Segmentation Fault when dealing with 2D Arrays

本文关键字:分割 故障 2D 数组 处理      更新时间:2023-10-16

我正在尝试动态地制作2D数组,然后将其迭代以检查其内容。每当我尝试使用索引数组的函数时,我都会得到分段故障。创建问题的两个函数是printg()和get()函数。我不确定我做错了什么,但是它们都不适合我。

任何帮助都会很棒。谢谢。

#ifndef _GRID_H
#define _GRID_H
#include <iostream>
using namespace std;
class Grid
{
    public:
        Grid();
        Grid(const Grid& g2);
        Grid(int x, int y, double density);
        Grid(string file);
        ~Grid();
        bool check(int x, int y); //check  if a cell is inhabited or not
        bool isEmpty();//check if a grid is living
        bool equals(const Grid& g2);//checks if two grids are equal
        void kill(int x, int y);//kill a cell
        void grow(int x, int y);//grow a cell
        int getSize();
        int getNumRows();
        int getNumCol();
        int getNumLiving();
        void printg(int r, int c);
        char get(int x, int y) const;
    private:
        int size; //number of cells in grid
        int row; //row length (number of columns)
        int column; //column length (number of rows)
        int num_living; //number of X's in the grid
        char** myGrid;
};
#endif

#include "Grid.h"
#ifndef _GRID_C
#define _GRID_C
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
//compile with g++ -I /home/cpsc350/GameOfLife Grid.cpp
using namespace std;
Grid::Grid() //do i need a default constructor????
{
    char myGrid[10][10] = {{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};
    row = 10;
    column = 10;
    size = 100;
}
Grid::Grid(const Grid& g2)//copy constructor/////////////help
{
    size = g2.size;
    row = g2.row;
    column = g2.column;
    num_living = g2.num_living;
    char** myGrid = new char*[row];
    for(int i = 0; i < row; i++)
        myGrid[i] = new char[column];
    for(int i1 = 0; i1 < row; i1++)
    {
        for(int i2 = 0; i2 < column; i2++)
        {
            //copy(&g2[i1][i2], &g2[i1][i2]+row*column,&myGrid[i1][i2]);
            myGrid[i1][i2] = g2.get(i1,i2);
        }
    }
}
Grid::Grid(int x, int y, double density)
{
    char** myGrid = new char*[x];
    for(int i = 0; i < x; i++)
        myGrid[i] = new char[y];
    row = x;
    column = y;
    size = x*y;
    num_living = size * density;
    string str = "";
    for(int a = 0; a < num_living; a++)//adds the density of X's to a string
    {
        str += 'X';
    }
    for(int a = 0; a < size - num_living; a++)//adds the rest to the string
    {
        str += '-';
    }
    int randnum;
    //randomly generates indicies in the string str and puts them into the array
    for(int i1 = 0; i1 < column; i1++)
    {
        for(int i2 = 0; i2 < row; i2++)
        {
            //generate random numbers from index 0 to length of string - 1
            if(str.length()>1)
            {
                randnum = (rand()%(str.length()-1))+1;
            }
            else
            {
                randnum = 0;
            }
            myGrid[i1][i2] = str[randnum];
            str.erase(randnum);
        }
    }
}
Grid::Grid(string file)
{
    num_living = 0;
    //code to create a 2d array from a filepath
    ifstream openfile(file);
    //error handling
    if(! openfile)
    {
        cout << "Error, file could not be opened" << endl;
        exit(0);
    }
    openfile >> column;//gets number of rows
    openfile >> row;//gets number of columns
    size = row*column;
    char** myGrid = new char*[row];
    for(int i = 0; i < row; i++)
        myGrid[i] = new char[column];
    for(int x = 0; x<column; x++)
    {
        for(int y = 0; y<row; y++)
        {
            openfile >> myGrid[x][y];
            if(! openfile)//error handling
            {
                cout << "Error reading file at " << row << "," << column << endl;
            }
            if(myGrid[x][y] == 'X')
            {
                num_living++;
            }
        }
    }
    openfile.close();
}
Grid::~Grid()
{
    if(myGrid)
    {
        for(int i = 0; i < row; i++)
        {
            delete []myGrid[i];
        }
        delete []myGrid;
    }
}
void Grid::kill(int x, int y)
{
    if(myGrid[x][y] == 'X')
    {
        num_living--;
    }
    myGrid[x][y] = '-';
}
void Grid::grow(int x, int y)
{
    if(myGrid[x][y] == '-')
    {
        num_living++;
    }
    myGrid[x][y] = 'X';
}
bool Grid::check(int x, int y)
{
    if(y<0 || x<0)
    {
        return(false);
    }
    return (myGrid[x][y] == 'X');
}
bool Grid::isEmpty()
{
    return (num_living == 0);
}
bool Grid::equals(const Grid& g2)
{
    if(size != g2.size) //checks if sizes are equal
    {
        return false;
    }
    if(row != g2.row)//checks if numRows are equal
    {
        return false;
    }
    if(column != g2.column)//checks if numCol are equal
    {
        return false;
    }
    if(num_living != g2.num_living)//checks if numliving are equal
    {
        return false;
    }
    for(int x = 0; x < row; x++)//checks each element
    {
        for(int y = 0; y < column; y++)
        {
            if(myGrid[x][y] != g2.get(x,y))
            {
                return false;
            }
        }
    }
    return true;
}
int Grid::getSize()
{
    return(size);
}
int Grid::getNumRows()
{
    return(column);
}
int Grid::getNumCol()
{
    return(row);
}
int Grid::getNumLiving()
{
    return(num_living);
}
void Grid::printg(int r, int c)
{
    for(int x = 0; x < r; x++)
    {
        for(int y = 0; y < c; y++)
        {
            cout << myGrid[x][y];
        }
    cout << endl;
    }
}
char Grid::get(int x, int y) const
{
    return myGrid[x][y];
}
#endif

我首先看到的问题是您的默认和复制构造函数都不会初始化mygrid。您在其中所做的将创建一个带有"阴影" MyGrid的名称的附加数组。相反,您必须这样做:

Grid::Grid(const Grid& g2)
{
    size = g2.size;
    row = g2.row;
    column = g2.column;
    num_living = g2.num_living;
    myGrid = new char*[row]; // removed "char**" at the start of this line
    for(int i = 0; i < row; i++)
        myGrid[i] = new char[column];
    for(int i1 = 0; i1 < row; i1++)
    {
        for(int i2 = 0; i2 < column; i2++)
        {
            //copy(&g2[i1][i2], &g2[i1][i2]+row*column,&myGrid[i1][i2]);
            myGrid[i1][i2] = g2.get(i1,i2);
        }
    }
}

您的默认构造函数有相同的问题。但是请注意,您不能用牙套初始化它。但是,如果您不使用它,则不必拥有默认的构造函数。