Is the memory in std::array contiguous?

Riley picture Riley · Jul 9, 2011 · Viewed 8.5k times · Source

Is the memory in std::array contiguous? Is the following valid/good practice?

std::array<type1,Num> arr = //initialize value
type1 * ptr = &arr[0];

Could I then pass ptr to functions expecting a c-style array?

Answer

Xeo picture Xeo · Jul 9, 2011

Yes, it is contiguous, as it is basically (and actually) a type arr[10];, but with STL like interface. It also doesn't decay to a pointer on the slightest provocation.

You can safely pass &arr[0] to a function expecting a C-style array, that's the design goal of it. To use it with the STL algorithms however, just use the begin and end functions:

// either members
std::sort(arr.begin(), arr.end());
// or free from <iterator>
std::sort(std::begin(arr), std::end(arr));

For the language lawyer part, §23.3.2.1 [array.overview] p1:

The header <array> defines a class template for storing fixed-size sequences of objects. An array supports random access iterators. An instance of array<T, N> stores N elements of type T, so that size() == N is an invariant. The elements of an array are stored contiguously, meaning that if a is an array<T, N> then it obeys the identity &a[n] == &a[0] + n for all 0 <= n < N.

And §23.3.2.1 [array.overview] p2:

An array is an aggregate (8.5.1) that can be initialized with the syntax

  • array<T, N> a = { initializer-list };

Also, in p3, listing the members of std::array:

T elems[N]; // exposition only
[ Note: The member variable elems is shown for exposition only, to emphasize that array is a class aggregate. The name elems is not part of array’s interface. —end note ]