Tami
Tami

Reputation: 153

Segfault when accessing array member of class

There are classes Field and Cell in my program and a few classes inherited from Cell. Main function works with Field, which has an array member containing pointers to cells of different classes. The cells are created in one method and I get Segfault when trying to access them in another methods. I feel that there must be a wrong array creation but have no ideas how to fix it. I tried to change array of pointers just to array of cells but got errors even in earlier stages of program.

To avoid putting here too much code: in main function first field is created as Field myfield; and then called functions for it: SetName, SetSize, CreateCells. Then I try to draw ConsoleDraw(&myfield); a field with next function:

void ConsoleDraw(Field *f)
{
    Cell* cell;

    for (int i=0; i<f->GetHeight(); i++)
    {
        for (int j=0; j<f->GetWidth(); j++)
            std::cout << f->GetCell(i,j)->GetType();

        std::cout << std::endl;
    }

    std::cout << std::endl;
}

Here is code for classes:
Field.h:

class Field
{
public:
    //some methods
    void ChangeCell(int i, int j, int type);
    void CreateCells();
    Cell* GetCell(int i, int j);

private:
    //some variables
    Cell*** cells;
};

Field.cpp:

void Field::CreateCells()
{
    cells = new Cell**[height];
    for (int i=0; i<height; i++)
    {
        cells[i] = new Cell*[width];

        for (int j=0; j<width; j++)
            ChangeCell(i,j,0);
    }

    for (int i=0; i<height; i++)
    for (int j=0; j<width; j++)
        cells[i][j]->SetNeighb();//operating with variables of single cell
}

void Field::ChangeCell(int i, int j, int type)
{
    if (cells[i][j]) delete cells[i][j];

    switch (type)
    {
        case 0:
            cells[i][j] = new Cell(0);
            break;
        case 1:
            cells[i][j] = new Cell(1);
            break;
        case 2:
        {
            cells[i][j] = new MovingCell;
            }
            break;
        case 3:
        {
            cells[i][j] = new CreatingCell;
            }
            break;
        case 4:
        {
            cells[i][j] = new KillingCell;
            }
            break;
        case 5:
        {
            cells[i][j] = new DyingCell;
            }
            break;
        default:
            if (type<10)
            {
                cells[i][j] = new DyingCell;
                cells[i][j]->SetChar(type-4);
            }
            else
            {
                cells[i][j] = new MovingCell;
                GetCell(i,j)->SetChar(type-10);
            }
    }

    cells[i][j]->SetCoordinates(j,i);
    cells[i][j]->SetOwner(this);
}

Cell* Field::GetCell(int i, int j)
{
    return cells[i][j];       //Here I got an error. 
}

I think there is no need in posting Cell class as all problems appear in operating with Field. Thank you in advance for any ideas of initialising that array correctly.

Upvotes: 0

Views: 407

Answers (1)

Johannes Overmann
Johannes Overmann

Reputation: 5151

The line if (cells[i][j]) delete cells[i][j]; assumes that all cells have been allocated with new, but there are many cases in the switch statement below where cells are not allocated with new but rather point to shared locations. This looks unclean to me and can for sure cause segfaults.

Next error: You are assigning pointers to temporary objects in the default clause in the switch statement in ChangeCell. Any access to them will cause segfaults sooner or later. Any call to delete on them will cause segfaults.

Upvotes: 1

Related Questions