2

I need to allocate a vector of rows where row contains a vector of rows. I know that a vector would be contiguous. I wanted to know whether a vector of vectors would also be contiguous. Example code is given below

vector<long> firstRow;

firstRow.push_back(0);

firstRow.push_back(1);

vector<long> secondRow;

secondRow.push_back(0);

secondRow.push_back(1); 

vector< vector < long> > data;

data.push_back(firstRow);

data.push_back(secondRow);

Would the sequence in memory be 0 1 0 1?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
user1150989
  • 493
  • 1
  • 4
  • 9

6 Answers6

19

In short, no. This is what actually happens:

enter image description here

Todd Li
  • 3,209
  • 21
  • 19
5

As others have said, no: nested vectors are not contiguous (nested arrays are the same, by the way; a statically sized array is an exception).

The way to implement a contiguous array of arrays (and generally any dense matrix) in C++ (and many other languages) is to have a flat array and calculate the indices manually:

typedef std::vector<long> matrix_t;

matrix_t M(width * height);
// Assign to index i, j:
M[i + j * width] = value;

… of course this should be encapsulated appropriately into a class.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
3

Nope, use boost::multi_array<long, 2> instead.

user541686
  • 205,094
  • 128
  • 528
  • 886
1

No. The vectors do not somehow communicate with one another in order to achieve one, large, contiguous storage space as they are added to parent vectors.

In this case, the storage used for the instances of firstRow and secondRow is contiguous, per the spec. However, vectors use heap storage for their elements, and it is very (very) unlikely that the two sub vectors will have, by coincidence, shared a single block for their respective allocations.

Don't confuse your elements (the vectors) with your elements individual allocations. It's those allocations which matter, and in this case you will be hopping around memory traversing them. A vector of vectors is not a good idea from a data locality perspective.

Want one large chunk of memory? Use an array.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • Thank you. How would you suggest I go about achieving data locality without using malloc and managing it on my own? – user1150989 Oct 21 '13 at 20:57
  • @user1150989: the low-tech method is to just allocate a vector (width*height) long and do the math yourself with it (i.e. to access the element (x,y) you do `vector[y*width+x]`). – Matteo Italia Oct 21 '13 at 21:21
0

Considering that vectors tend to automatically re-size themselves, I'd assume that it can't be contiguous.

Sure, the references to the vectors could be contiguous, but the data itself can't all be.

If a vector of vectors were continuous, how would individual vectors re-size themselves?

0

vector< vector < long> > data would hold a pointer to a contiguous array of vector<long> objects. Each of which, in turn, would hold a pointer to a contiguous array of long. But if you expect all longs together, as would be the case with long[10][20], then no, that's not how it works.

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85