Search code examples
c++for-loopnested-loopsstdvectoroutofrangeexception

2d push_back doesnt save to vector values


I have a 2d vector which should save x and y coordinates. Everything works as intended except saving this values to vector. What did I do wrong?

void Game::GetShips(Board &b)
{
    vector<vector<int>> shipCors;

    for (int i = 0; i < BOARDSIZE; i++) {

        for (int j = 0; j < BOARDSIZE; j++) {
            if (b.getSpaceValue(i, j) == SHIP) {
                cout << "X :"<< i<<"\n Y:"<<j<<'\n';
                shipCors[i].push_back(j);
              
            }
        }

    }
    cout<< shipCors.size()<<'\n';
 }

Solution

  • You declared an empty vector

    vector<vector<int>> shipCors;
    

    So you may not use the subscript operator

    shipCors[i].push_back(j);
    

    You could write

    for (int i = 0; i < BOARDSIZE; i++) {
    
        shipCors.resize( shipCors.size() + 1 );
        for (int j = 0; j < BOARDSIZE; j++) {
            if (b.getSpaceValue(i, j) == SHIP) {
                cout << "X :"<< i<<"\n Y:"<<j<<'\n';
                shipCors[i].push_back(j);
              
            }
        }
    
    }
    

    Pay attention to that as you are using the index i then you need to add a "row" of the vector even if the row will be empty after executing the inner for loop.

    It will be even better to resize the vector initially before the for loops like

    vector<vector<int>> shipCors;
    shipCors.resize( BOARDSIZE );
    
    for (int i = 0; i < BOARDSIZE; i++) {
    
        for (int j = 0; j < BOARDSIZE; j++) {
            if (b.getSpaceValue(i, j) == SHIP) {
                cout << "X :"<< i<<"\n Y:"<<j<<'\n';
                shipCors[i].push_back(j);
              
            }
        }
    
    }
    

    An alternative approach is to have a vector declared like

    std::vector<std::pair<int, int>> shipCors;
    

    In this case your loop will look like

    for (int i = 0; i < BOARDSIZE; i++) {
    
        for (int j = 0; j < BOARDSIZE; j++) {
            if (b.getSpaceValue(i, j) == SHIP) {
                cout << "X :"<< i<<"\n Y:"<<j<<'\n';
                shipCors.emplace_back(i, j);
              
            }
        }
    
    }
    

    Or to keep the data sorted you can declare a set like

    std::set<std::pair<int, int>> shipCors;