处理二维数组时出现分段错误[关闭]

Posted

技术标签:

【中文标题】处理二维数组时出现分段错误[关闭]【英文标题】:Segmentation Fault when dealing with 2D Arrays [closed] 【发布时间】:2019-03-05 10:49:57 【问题描述】:

我正在尝试动态创建二维数组,然后应该对其进行迭代以检查其内容。每当我尝试使用索引数组的函数时,我都会遇到分段错误。造成问题的两个函数是 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

【问题讨论】:

char myGrid[10][10] 不是 this-&gt;myGrid。我没有阅读所有代码,但怀疑您从未在任何地方使用this-&gt;myGrid 没有找到好的骗子,也许这已经足够接近了:***.com/questions/32311372/… 你的代码违反了The Rule of Three:赋值运算符没有重载。 实际帮助:在调试器下运行,或者用一个来检查你的核心文件。分段错误充满信息,包括它们发生时的完整程序状态。如果这对你没有任何帮助,请使用 valgrind 或 asan 查找非本地内存损坏。如果您需要进一步的帮助,您需要努力将您的代码缩减为 minimal complete verifiable example #define _GRID_H 该标识符是保留的。通过定义它,您的程序将具有未定义的行为。您应该使用另一个标头保护。 【参考方案1】:

我首先看到的问题是您的默认构造函数和复制构造函数都没有初始化 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);
        
    

你的默认构造函数也有同样的问题。但请注意,您不能用大括号对其进行初始化。但是如果你不使用它,你不必有一个默认的构造函数。

【讨论】:

以上是关于处理二维数组时出现分段错误[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Swift:填充二维数组时出现索引超出范围错误

尝试在 C 中使用 realloc 扩展数组时出现分段错误错误 [关闭]

填充数组时出现分段错误[关闭]

初始化数组时出现段错误

大型二维数组给出分段错误

动态二维数组。为啥是分段错误?