Search code examples
c++pointersvectorreference

Not able to add pointer to a vector in C++


I am trying to implement a grid system to detect colission between tanks in a game.

My goal is to have around 40 cells which all have a vector with tank pointers. The tank should be in the right grid cell saved and updated whenever it moves to another.

When for the first time adding a tank pointer to a vector the application crashes. This is what my code looks like:

    vec2 position{ start_blue_x + ((i % max_rows) * spacing), start_blue_y + ((i / max_rows) * spacing) };
    Cell* tank_cell = Cell::find_cell_for_tank(position.x, position.y, cells);
    Tank tank = Tank(position.x, position.y, BLUE, tank_cell, &tank_blue, &smoke, 1100.f, position.y + 16, tank_radius, tank_max_health, tank_max_speed);
    tank_cell->tanks.push_back(&tank);

cell.h

Cell(int column, int row, vector<Tank*> tanks);

It seems to happen at the last line where I push the tank in the cell.

Exception thrown: Access violation reading 

Cell::find_cell_for_tank()

    Cell* Cell::find_cell_for_tank(int pos_x, int pos_y, vector<Cell*>& cells)
{
    int tank_col = pos_x / CELL_WIDTH;
    int tank_row = pos_y / CELL_HEIGHT;
    
    for (int i = 0; i < cells.size(); i++) {
        if ((*cells.at(i)).column == tank_col && (*cells.at(i)).row == tank_row)
        {
            return cells.at(i);
        }
    }

    Cell* new_cell = &Cell(tank_col, tank_row, {});
    cells.push_back(new_cell);
    return new_cell;
}

Solution

  • This is bugged

    Cell* new_cell = &Cell(tank_col, tank_row, {});
    cells.push_back(new_cell);
    return new_cell;
    

    You are creating a temporary Cell object, pushing a pointer to the object onto a vector and returning a pointer to that temporary object.

    The Cell object does not exist after the first line of code (it's a temporary), but those pointers to it still do. This is called a dangling pointer, and using either of those pointers is likely to crash your code.

    Try not to use so many pointers. There is no reason for them, use std::vector<Cell> not std::vector<Cell*> and std::vector<Tank> not std::vector<Tank*>.

    If you don't use pointers you cannot have dangling pointers.