vvint1
and vvint2
memory requirements are:
- (on stack, in the example)
sizeof(vector<vector<int>>)
for the objects themselves, which is the same (vector
is 2–3 pointers usually, regardless of the inner type);
- (on heap)
2 * nvvec * sizeof(vector<int>)
for the contents (nvvec
initially and nvvec
push_back
-ed in the loop); again, that’s the same for vvint1
and vvint2
;
- (on heap) contents of each vector stored in these vectors. Since vectors don’t share memory, and you store them by value,
nvec * nnvec * sizeof(int)
. Again, the same.
So the overall requirements are the same:
sizeof(vector<vector<int>>) + nvvec * sizeof(vector<int>) + nvec * nnvec * sizeof(int)
Plain vector<int>
would take less space ofc as item 2 wouldn’t apply. But what is more important is that in vvint_t
, inner vectors may be of different lengths, and resizing any inner vector doesn’t affect others. But that adds complexity, so unless you really need that, it’s simpler to use flat vector and calculate index; imaging libraries do it that way.
Regarding second part, both vitest
s are copied on each push_back. But since C++11, you can write vvint1.push_back(std::move(vitest1));
(or vvint1.emplace_back(std::move(vitest1));
) to move instead. For vectors that means the newly-constructed vector takes ownership of vitest1
contents without copying it (so vitest1
becomes empty). That doesn’t change memory requirements but reduces allocations as the space allocated by vitest
(at construction) would be reused instead of being freed (at destruction, at end of each iteration).