C-Style array Vs std::array

In this article we will about study C-style array vs std::array. A std::array should have same run-time performance as a c-style array. In STL there are two type of arrays, first is fixed length array means std::array and other type is dynamic array means std::vector. 

Introduced in C++11, std::array has a unique characteristic among all sequential containers of the STL, you can not adjust it size during run-time.

Initialization of std::array


std::array initialized by following ways: 

// Required header file
#include <array> 
 
// Declare an integer array with length 4
std::array<int, 4> myArray; 
// Initialization list
std::array<int, 5> myArray = { 9, 8, 5, 3, 1 };
// Uniform initialization
std::array<int, 5> myArray { 9, 8, 5, 3, 1 }; 
// The 10 elements are not initialized.
std::array<int,10> myArray ; 
The 10 elements are value-initialized to zero.
std::array<int,10> myArray {};
// Legal, elements 3 and 4 are set to zero! 
std::array<int> myArray = { 9, 7, 5}; 
// Illegal, array length must be provided
std::array<int, > myArray = { 9, 8, 5, 3, 1 };
// Illegal, too many elements in initializer list!
std::array<int, >  myArray = { 0, 1, 2, 3, 4, 5 }; 

Index access


std::array supports the index access in 3 ways :

  1. myArray[n-1]:  Access to the nth element without a check of the array boundaries.
  2. myArray.at(n-1): Access to the nth element with a check of the array boundaries. Eventually, a std::range_error exception is thrown.
  3. std::get(myArray): Access to the nth element with a check of the array boundaries at compile time. The syntax is according to std::tuplestd::get(myArray) shows the relationship of std::array with std::tuplestd::array is a homogeneous container of fixed size while std::tuple is a heterogeneous container of fixed size.

Example: C-Style array Vs std::array

#include <iostream>
#include <array>
#include <vector>
 
 
int main()
{
  // c-style array
  int array1[3] = {1, 2, 3};
 
  array1[1] = 15;
 
  std::cout << "size: " << (sizeof(array1) / sizeof(*array1)) << std::endl;
 
  for (auto element : array1)
  {
    std::cout << element << std::endl;
  }
   
  // std-style array
  std::array<int,3> array2 = { 4, 5, 6 };
 
  array2[1] = 25;
 
  std::cout << "size: " <<array2.size() << std::endl;
 
  for (auto element : array2)
  {
    std::cout << element << std::endl;
  }
}
Here, array2.size() will return array size, no need of calculation like - (sizeof(array1) / sizeof(*array1)).


Array as method parameter:


Using below way you can pass std::array as string parameter : 
#include <iostream>
#include <vector>
#include <array>

void PrintArray(int* values, int size)
{
  std::cout << "size: " << size << std::endl;
 
  for (int i = 0; i < size; ++i)
  {
    std::cout << values[i] << std::endl;
  }
}
 
void PrintArray(const std::array<int,3> &values)
{
  std::cout << "size: " << values.size() << std::endl;
 
  for (auto& value : values)
  {
    std::cout << value << std::endl;
  }
}
 
int main()
{
  int array1[3] = { 1, 2, 3 };
  PrintArray(array1, 3);
   
  std::array<int,3> array2 = { 4, 5, 6 };
  PrintArray(array2);
}

Array as return value


std::array can be used as return value. Example -
#include <iostream>
#include <vector>
#include <array>

int* CreateArray()
{
  int* array = new int[3] { 1, 2, 3 };
  return array;
}
 
std::array<int,3> CreateStdArray()
{
  std::array<int,3> array = { 4, 5, 6 };
  return array;
}
 
int main()
{
  // c-style array
  int* array1 = CreateArray();
  int size = 3;   // you have to know the size of the array
 
  for (int i = 0; i < size; ++i)
  {
    std::cout << array1[i] << std::endl;
  }
 
  delete[] array1; // you have to delete the array
    
  // std-style array
  std::array<int,3> array2 = CreateStdArray();
 
  for (auto element : array2)
  {
    std::cout << element << std::endl;
  }
}
In this case called method should know data type and size of array before calling function, for variable length of array std::array is not useful.

Sort std::array


Using std::sort algorithm we can sort std::array elements. If any error occurred during execution will throw an out of range exception..

#include <iostream>
#include <vector>
#include <array>
#include <algorithm>

int main()
{
  // c-style array
  int array1[3] = {7, 5, 3};
   
  std::sort(std::begin(array1), std::end(array1));
 
  for (auto element : array1)
  {
    std::cout << element << std::endl;
  }
   
  // std-style array
  std::array<int,3> array2 = { 7, 5, 3 };
 
  std::sort(array2.begin(), array2.end());
   
  for (auto element : array2)
  {
    std::cout << element << std::endl;
  }
}

Multi-dimensional arrays


The std::array as well as the c-style array support multidimensions. These multidimensions are designed as arrays of nested arrays. 
#include <iostream>
#include <array>
int main()
{
  // c-style array
  int array1[2][3] = { { 1, 2, 3 }, { 4, 5, 6} };
 
  array1[0][1] = 10;
   
  for (auto &row : array1)
  {
    for (auto &element : row)
    {
      std::cout << element << std::endl;
    }
  }     
 
  // std-style array
  std::array<std::array<int,3>, 2> array2{ { { 7, 8, 9 }, { 10, 11, 12 } } };
 
  array2[0][1] = 20;
 
  for (auto &row : array2)
  {
    for (auto &element : row)
    {
      std::cout << element << std::endl;
    }
  }
}

Summary


The std::array is designed as zero-overhead wrapper for c-style arrays. Therefore, it comes with all the advantages of a c-style array and ads the additional advantages of C++ containers. I would recommend to use std::arrays except you have a rare special use case which comes with good reasons to use a c-style array.

Advantages of std::array
  • Perfectly matches with the strict type system concept of c++
  • Copy semantic / no pointer decay / the array doesn’t convert to a pointer unless you explicitly ask it to
  • It knows its size
  • Range check in debug builds
  • No memory overhead beyond what it needs to hold its elements
  • Same performance as a c-style array
  • Direct support of use in STL algorithms

Disadvantages of std::array
  • Slightly more awkward syntax for declaration of the array, especially when creating multi-dimensional arrays

No comments:

Post a Comment