3

Why does a two-dimensional array of int initialize contiguously? Meanwhile the two dimensional vector is initialize per set of numbers.

int main()
{
  array<array<int, 2>, 2> td{ 2, 6, 4, 8 }; //array of arrays
  for (int i = 0; i < 2; ++i)
    for(int j = 0; j < 2; ++j)
      cout << td[i][j] << ' ';

  cout << endl;

  vector<vector<int>> vtd{ { 5, 1 }, { 0, 2 } };  //vector of vectors
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j)
      cout << vtd[i][j] << ' ';

  return 0;
}

Here are the results:

2 6 4 8
5 1 0 2
2
  • Most compilers should give you a warning for the std::array initialization, as it's really missing braces. Commented Feb 21, 2014 at 20:00
  • I was getting a compile error if I initialize using { {0,1}, {2,3} } from the VS2013 MSVC compiler. Then I used {0,1,2,3} and it works. Commented Feb 21, 2014 at 20:03

4 Answers 4

3

std::array is an aggregate. When an aggregate is initialized with a braced-init-list like this, each subaggregate, in order, takes as many elements from the list as it requires, and the remainder of the list is used to initialize the next element, and so on. In particular, this means that the first array in td takes the first two initializers (since it has two elements) and the second array takes the remaining two.

std::vector is not an aggregate, and has an explicitly defined constructor that takes std::initializer_list as an argument, which determines the semantics of list-initialization.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. To add, according to The C++ Programming Language (4th ed.) it is a fixed-size array of N contiguous elements of type T.
1

The difference between an array of arrays and a vector of vectors is the same as a normal array of arrays versus a pointer to pointer.

The std::array class is quite close to normal arrays (which has to be contiguous), while std::vector is closes to a pointer.

Comments

1

std::vector is an object encapsulating a set of internal state: { T* data, size_t count, size_t capacity }. The actual contents of a vector are stored off in memory somewhere else.

By contrast, std::array is an encapsulation layer around a C-style array. It does not have internal state, but sits directly over a C-array.

std::vector<int> v;
v.reserve(4);
std::array<int, 4> a;

After this, what you have on the stack is as follows:

[ int* v.data ]
[ size_t v.count = 0 ]
[ size_t v.size = 4 ]
[ int[4] ]

As a result, your 2-tier std::vector is actually a vector of objects,

[ std::vector<int>* v.data --> points to second tier object in heap memory ]
[ size_t v.count ]
[ size_t v.size ]

whereas the std::array is actually just a cover for int a[2][2], which initializes exactly the way you would expect.

Comments

0

std::array is a very thin wrapper around a static array. It is allocated at compile time, with a known size, and each element is guaranteed to be contiguous, so when you have an array of arrays, they will all be contiguous.

Example:

std::array<T, 4> a;
|   a[0]   |   a[1]   |   a[2]   |   a[3]   |

std::array<std::array<T, 2>, 2> b;
|   a[0][0]   |   a[0][1]   |   a[1][0]   |   a[1][1]   |

Since the first array (a[0]) is guaranteed to be contiguous (as is the second array), and the parent wrapper array is also guaranteed to be contiguous, the entire structure will be contiguous.

For a vector, it is determined at runtime. The dynamic array of a vector is guaranteed to be contiguous, if it is a vector of vectors, each element in the parent vector has a pointer to a separate block of contiguous memory (each "child" vector has a size, capacity, and pointer to a block of contiguous memory).

The analogy follows:

T t[...][...] ====> std::array<std::array<T, ...>, ...>
T** t         ====> std::vector<std::vector<T>>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.