Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the Issues with a vector-of-vectors?

I've read that a vector-of-vectors is bad given a fixed 2nd dimension, but I cannot find a clear explanation of the problems on http://www.stackoverflow.com.

Could someone give an explanation of why using 2D indexing on a single vector is preferable to using a vector-of-vectors for a fixed 2nd dimension?

Also, I'm assuming that a vector-of-vectors is the preferable data structure for a 2D array with a variable 2nd dimension? If there is any proof to the contrary I'd love to see that.

like image 518
Jonathan Mee Avatar asked Jul 07 '16 11:07

Jonathan Mee


People also ask

Can you have a vector of vectors?

Vector of Vectors is a two-dimensional vector with a variable number of rows where each row is vector. Each index of vector stores a vector which can be traversed and accessed using iterators. It is similar to an Array of Vectors but with dynamic properties.

Do vectors cause memory leaks?

std::vector does not cause memory leaks, careless programmers do. You should also include an example that actually exhibits the behavior you are experiencing, including calls to the CRT debug API. There's a good possibility that you're incorrectly interpreting the leaks based on when they are reported.

What happens when a vector goes out of scope?

The second way to delete a vector is just to let it go out of scope. Normally, any non-static object declared in a scope dies when it goes out of scope. This means that the object cannot be accessed in a nesting scope (block).


2 Answers

For a std::vector the underlying array is dynamically allocated from the heap. If you have e.g. std::vector<std::vector<double>>, then your outer vector would look like

{v1, v2, v3, v4, ... vn}

This looks like each of the inner vectors will be in contiguous memory, and they will, but their underlying arrays will not be contiguous. See the diagram of the memory layout in this post. In other words the you cannot say that

&(v1.back()) + 1 == &(v2.front()) // not necessarily true!

Instead if you used a single vector with striding then you would gain data locality, and it would inherently be more cache friendly as all your data is contiguous.

For the sake of completeness, I would use neither of these methods if your matrix was sparse, as there are more elegant and efficient storage schemes than straight 1D or 2D arrays. Though since you mentioned you have a "fixed 2nd dimension" I will assume that is not the case here.

like image 122
Cory Kramer Avatar answered Oct 18 '22 08:10

Cory Kramer


I shall answer with a simple analogy.

What is "better" in general out of the two things?

  1. A telephone book where each entry is a code referring to a different book that you have to find and read to discover someone's telephone number
  2. A telephone book that lists people's telephone numbers

Keeping all your data in a single big blob is more simple, more sensible, and easier on your computer's cache. A vector with N vectors inside it is much more operationally complex (remember, each of those requires a dynamic allocation and size management operations!); one vector is, well, one vector. You haven't multiplied the workload by N.

The only downside really is that to simulate 2D array access with a 1D underlying data store, you need to write a facade. Fortunately, this is very easy.

Now for the subjective part: on balance I'd say that it's worthwhile unless you're really in a rush and your code quality doesn't particularly matter.

like image 26
Lightness Races in Orbit Avatar answered Oct 18 '22 06:10

Lightness Races in Orbit