Array in C++ (STL)

In this article, we will learn about a STL Container std::array<> in C++. We will discuss its usage details with examples, and understand how its different from an old C style array.

What is std::array<>?

The std::array<> is a STL Container, and it is similar to the C style fixed size array. It can store elements of same type, and we need to specify its size while creating an std::array<> object, because it is constructed at the compile time. Just like the old fixed size array.

But the question is, if std::array<> is similar to C-Style fixed size array, then why do we need it?

std::array<> vs C-Style fixed size array

Internally std::array<> contains the old C style array, but it provides additional features on top of that fixed size array. Like,

  • It provides the support of iterators, just like other STL containers. Basically it provides the member functions to get the access of iterators. We can use the begin() and end() functions to get the iterator pointing to the start and end of the array. We can use these iterators to navigate over the elements of arraym amd use it with the generic functions.
  • It provides the size() function which tells us about the size of the array. In the old C-Style array we need to calculate the size using sizeof(arr)/sizeof(arr[0]) expression. But in std::array we can directly call the size() function to get the size of array.
  • It provides helping functions like at(), to access the array elements in range bound manner.

Syntax of std::array<>

To use the std::array<> we need to include the header file <array> i.e.

#include <array>

To create a std::array<> object we need to provide the two template parameters. Syntax is as follows,

std::array<data_type, size_of_array> arr;

Two template parameters are,



    • data_type : Data type of elements that std::array<> object will store.
    • size_of_array : Maximum Number of elements that can be stored in this std::array<> object i.e. the size of the array.

    We need to provide these two as the template parameters, and it will create an std::array<> object, which can contain the N elements of specified data type. Where N is the size of array, that is specified as second template parameter and data type is specified as the first template parameter.

    Creating std::array<> objects

    To create an std::array<> object, we will use the above mentioned syntax, i.e. we will provide data type and size as template parameters while creating the std::array object.

    For example, to create an int array of size 5, we need to provide int and 5 as template parameters while creating the std::array object.

    // Create an int array of size 3
    std::array<int, 3> arr;
    

    Let us see an example, where we will create an std::array<> object that can hold 5 integers, and then we will use the size() function of array to get its size.

    #include <iostream>
    #include <array>
    
    int main() {
    
        // Create an int array of size 5
        std::array<int, 5> arr;
    
        // Print the size of array
        std::cout<< "Size of Array : " << arr.size() << std::endl;
    
        return 0;
    }
    

    Output:

    Size of Array : 5
    

    An integer array of size 5 was created, but all the elements in this array will be uninitialized, and will contain the garbage values.

    We can create an array and initialise it with hard coded values using the initializer list. Let’s see an example, where we will create an int array of size 5, and initialize it with 5 values.

    #include <iostream>
    #include <array>
    
    int main() {
    
        // Create an int array of size 5
        std::array<int, 5> arr = {23, 56, 23, 56, 22};
    
        // Print the size of array
        std::cout<< "Size of Array : " << arr.size() << std::endl;
    
        return 0;
    }
    

    Ouput:

    Size of Array : 5
    

    It created an int array, initialzed with 5 given values. We can check the size of the array using the std::array::size() function.

    How to Access elements in std::array<>

    To access the elements from this array we can either use the array::at() function or the subscript operater i.e. []. Both provides the facility of random access. As indexing starts from zero in C++, so to access the element at ith position, we need to provide the index as i-1.

    Access std::array<> elements using [] operator

    Let us see an example, where we will create a array of five integers and then we will access the 3rd element from this array using the [] operator.

    #include <iostream>
    #include <array>
    
    int main() {
    
        // Create an int array of size 5
        std::array<int, 5> arr {11, 56, 23, 56, 22};
    
        // Access 3rd element in array
        int& value = arr[2];
    
        std::cout<< "3rd Element of Array is : " << value << std::endl;
    
        return 0;
    }
    

    Output:

    3rd Element of Array is : 23
    

    Here, we used the subscript operator to access an element from the array by its index position, just like an old C-style array, therefore we passed 2 as the the index value.

    But what if you pass an index position in [] opeartor, that is out of range? Basically what if the given index position is out of the bounds of the array? For example, suppose there is an array of size 5, and we try to access element at index 10 in this array using the [] operator. In that case, it will result in undefined behavior. This behaviour is similar to what happens in the C style array, when we try to access an element out of range. Let us see an example,

    #include <iostream>
    #include <array>
    
    int main() {
    
        // Create an int array of size 5
        std::array<int, 5> arr {11, 56, 23, 56, 22};
    
        // Access 10th element in array
        int& value = arr[10];
    
        std::cout<< "10th Element of Array is : " << value << std::endl;
    
        return 0;
    }
    

    Output:

    10th Element of Array is : 977891459
    

    As there were only 10 elements in the array, so when we tried to access the element at index 10, it returned a garbage value. It might be possible that in some cases, it crashes the application. To avoid this issue, we can use the at() function of std::array.

    Access std::array<> elements using at() function

    The std::array<> container provides a function at(). It accepts an index position as an argument and returns a reference to the element from array at that index position. It works like the [] operator of std::array, but if the given index does not exist in the array or it is greater than the size of std::array<>, then it will raise an exception out_of_range. Let’s see an example,

    #include <iostream>
    #include <array>
    
    int main() {
    
        // Create an int array of size 5
        std::array<int, 5> arr {11, 56, 23, 56, 22};
    
        // Access 10th element in array
        int& value = arr.at(10);
    
        std::cout<< "10th Element of Array is : " << value << std::endl;
    
        return 0;
    }
    

    Output:

    terminate called after throwing an instance of 'std::out_of_range'
      what():  array::at: __n (which is 10) >= _Nm (which is 5)
    Aborted (core dumped)
    

    So, this is one advantage of using std::array over old style array. It can help us avoid the undefined behaviour. We can catch the exception and gracefully handle it. Let’s see another example, were we will gracefully handle the exception,

    #include <iostream>
    #include <array>
    
    int main() {
    
        // Create an int array of size 5
        std::array<int, 5> arr {11, 56, 23, 56, 22};
    
        try
        {
            // Access 10th element in array
            int& value = arr.at(10);
            std::cout<< "3rd Element of Array is : " << value << std::endl;
        }
        catch(const std::out_of_range& expObj)
        {
            std::cerr << "Exception: " << expObj.what() << '\n';
        }
    
        std::cout<<"program is ending here \n";
        return 0;
    }
    

    Output:

    Exception: array::at: __n (which is 10) >= _Nm (which is 5)
    program is ending here 
    

    So, we handled the exception gracefully, and programmed continued after that.

    Using front() and back() functions to access std::array<> elements

    The std::array::front() function returns the first element of std::array<>. Whereas, the std::array::back() function returns the last element of std::array<>. Let’s see the example,

    #include <iostream>
    #include <array>
    
    using namespace std;
    
    int main() {
    
        // Create an int array of size 5
        array<int, 5> arr {11, 56, 23, 56, 22};
    
        cout<< "First element of array is: " << arr.front() << endl;
        cout<< "Last element of array is: " << arr.back() << endl;
    
        return 0;
    }
    

    Output:

    First element of array is: 11
    Last element of array is: 22
    

    std::array<> and Iterators

    An Iterator is an object, which behave like a pointer. It points to an element of the container and it provides the operator like ++ and --, to navigate over the other elements of container.

    The array::begin() function provides an iterator pointing to the start of the array. Whereas the array::end() function returns an iterator pointing to the element next to the end of the array. So we can use these iterators to iterate our all the elements of array, just like we use them with any other STL container. Also, this is not possible with the old C-Style fixed size arrays.

    Let’s see how to use the iterators with the std::array to iterate our all the elements of the array and print them one by one.

    #include <iostream>
    #include <array>
    
    int main() {
    
        // Create an int array of size 5
        std::array<int, 5> arr {11, 56, 23, 56, 22};
    
        // Iterate over all elements of array using a for loop
        // and iterators
        for(auto it = arr.begin(); it != arr.end(); it++)
        {
            // Print the element pointed by iterator
            std::cout<< *it << ", ";
        }
        std::cout<< std::endl;
    
        return 0;
    }
    

    Ouput:

    11, 56, 23, 56, 22,
    

    We can also use the std::array<> object with range based for loop to iterate over all its elements. Like this,

    #include <iostream>
    #include <array>
    
    int main() {
    
        // Create an int array of size 5
        std::array<int, 5> arr {11, 56, 23, 56, 22};
    
        // Iterate over all elements of array
        for(auto& elem: arr)
        {
            std::cout<< elem << ", ";
        }
        std::cout<< std::endl;
    
        return 0;
    }
    

    So the additional advantage of using std::array<> over C-style array, is that it will act like any existing container and we can easily use it in all the STL algorithms that uses iterators of containers for the processing.

    Passing std::array<> to a function

    Suppose we want to pass an arrays to a functions.

    In case of old style C Style array, we need to pass two arguments to the function i.e. a pointer, pointing to the start of array and size of array. Like,

    void display(int * arr, size_t len);
    

    It will cause the array decay, because inside the function arr, will act like an integer pointer instead of int array. But when we are using a std::array, we can just pass the array object as reference to another function. Like,

    #include <iostream>
    #include <array>
    
    template <typename T, size_t size> 
    void display(std::array<T, size> &arr)
    {
        // Iterate over all elements of array
        for(size_t i = 0; i < arr.size(); i++)
        {
            std::cout<< arr[i] << ", ";
        }
        std::cout<< std::endl;
    
    }
    
    int main() {
    
        // Create an int array of size 5
        std::array<int, 5> arr {11, 56, 23, 56, 22};
    
        display(arr);
    
        return 0;
    }
    

    Output:

    11, 56, 23, 56, 22, 
    

    As it has the size() member function, so we do not need to pass the size as a separate argument. We can use the arr, as an array in the function. Like, in the above example, we iterated over all the elements of array.

    Summary

    In this article, we learned that the std::array<> is a STL Container, and provides the functionality of a fixed size array. Thanks.

    Scroll to Top