JB_User JB_User - 3 months ago 8
C++ Question

C++: Problems with a vector of vectors of structs

I need a variable size 2-D matrix where each element is a struct. The number of rows is known at compile time and never changes. The number of columns is different for each row. I implemented this with a vector of vectors, but I don't know if I did it right:

struct MyStruct {
int a, b;
MyStruct(int arg_a, int arg_b) { a = arg_a; b = arg_b; };
};

int main(void) {
vector < vector< MyStruct > > myVVOfStructs;
myVVOfStructs.reserve(10); // Intended to reserve 10 rows of variable size vectors

vector< MyStruct > tmpVector = myVVOfStructs[5];
tmpVector.push_back(MyStruct(10, 20));

}


Is this the right way to do it? The above snippet works when I put it in a C++ file by itself. However, in my much larger C++ program, the above fails with this message

terminate called after throwing an instance of 'std::bad_alloc'


So, there must be a problem with the way I'm doing it, but it's complicated since it works in a simple C++ source file, but not in a larger more complicated program. Any ideas? Is there a better way to do it?

LATER EDIT: There's an answer to this question in another question titled "When should we use reserve() of vector?". The problem is that in order to find that answer, I'd already have to know that reserve() was the cause of the problem. As it stands, I never would have read the page with that title since I did not know reserve() was the cause of my problems. If I already knew that, then I would have known enough to figure the problem out by myself.

Answer

The method:

myVVOfStructs.reserve(10);

does not change the size of the vector itself. Reserve - Vector:

This function has no effect on the vector size and cannot alter its elements.

So, when you're trying to access the 6-th element with:

vector< MyStruct > tmpVector = myVVOfStructs[5];

That will produce an UB, because the myVVOfStructs[5] does not exists yet.


In order to change the size of the vector you should use the method:

mmVVOfStruct.resize(10);
Comments