2D vectors input in c++

I am a beginner in c++ so I was trying to solve a problem at codeforces and I have to make a 2d vector that have rows = 't' column = 'n[i]' and I tried too make it.

But when I run the program it crashes with error "vector subscript out of range" and I don't know how to fix it.

#include <iostream>
#include <vector>

using namespace std;

int main() {
int t;
cin >> t;
vector<int>n(t);
vector<vector<int>>x(t);

    for (int i = 0; i < t; i++) {
            cin >> n[i];
        for (int j = 0; j < n[i]; j++) {
            cin >> x[i][j];
        }
    }

    return 0;

}

Upvotes: 1

Views: 144

Answers (2)

francesco
francesco

Reputation: 7549

With this:

vector<vector<int>>x(t);

you initialize a vector with t elements, where each element is a std::vector<int> which is initialized with the default constructor. The default constructor gives an empty vector. So, what you have here is a t x 0 matrix, t lines and 0 columns.

When you access the vector x with

x[i][j]

you are asking to get the i-th element of x, which is a std::vector<int>, and from this, you want the j-th element. But there are actually 0 elements. Crucially, accessing the elements with [] does not carry any bounds checking. So the program will have undefined behavior.

In this part:

    for (int j = 0; j < n[i]; j++) {
        cin >> x[i][j];

you fill the element x[i] with n[i] ints. Knowing that this will be the size of x[i], you can fix the program adding

    x[i] = std::vector<int>(n[i]);

before the for (int j = 0; j < n[i]; j++) loop.

Or you could, for every inserted number, emplace_back a new element

    for (int j = 0; j < n[i]; j++) {
        int el;
        cin >> el;
        x[i].emplace_back(el);
    }

(For this solution you should not insert x[i] = std::vector<int>(n[i]); before the loop on j).

Upvotes: 3

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123431

std::vector<int>n(t); constructs a vector with t integers. The integers are default constructed (actually not sure, but anyhows...), they are initialized with 0.

std::vector<std::vector<int>>x(t); constructs a vector with t inner vectors. The inner vectors are default constructed, they are empty.

Trying to access elements that do not exist in cin >> x[i][j]; invokes undefined behavior. x[i] is empty vectors.

You can use the constructor that takes another paramter, the initial value. For t sized inner vectors:

std::vector<std::vector<int>> x(t,std::vector<int>(t));

Alternatively you could call resize:

for (int i = 0; i < t; ++j) {
     x[i].resize(t);

Or reserve and push_back:

for (int i = 0; i < t; ++j) {
     x[i].reserve(t);
     for (int j=0; j < t; ++j) {
         x[i].push_back(42);
     }
}

Upvotes: 3

Related Questions