Skip to content

Wiki

std::array

About 11 min read

1.What problem does this section solve?

C-style arrays (int arr[5] ) have many drawbacks: they cannot be directly assigned, they decay to pointers when passed to functions, losing size information, and they lack bounds checking. While std::vector is powerful, it uses dynamically allocated memory and incurs a slight overhead.

std::arrayWhat it solves is: when you need anarray with a size determined at compile time and allocated on the stackit provides a safe array that is as fast as a C array but has the STL container interface (it has size(), has iterators, and is assignable).

2.What is this feature?

std::array<T, N> is a container template in the STL that encapsulates a fixed-size array. Its size is determined at compile time, it does not dynamically allocate memory (it is on the stack), and it wraps a C array while providing the standard interface of an STL container.

3.C++ Standard Edition

C++11

4.Required header files

#include <array>

Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.

5.Basic syntax

std::array<元素类型, 大小> 变量名;            // 默认初始化(值未定义)
std::array<元素类型, 大小> 变量名 = {};        // 全部初始化为零
std::array<元素类型, 大小> 变量名 = {v1, v2, ...}; // 列表初始化

Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.

6.Common Usage

Operation Description
a[i] Random access (no bounds checking)
a.at(i) Random access (with bounds checking)
a.size() Returns the number of elements (compile-time constant)
a.empty() Whether it is empty (always false)
a.front() Returns the first element
a.back() Returns the last element
a.fill(val) Fills all elements with val
a.data() Returns a pointer to the underlying C array

7.Example code

7.1.Example 1: Creating an array and accessing elements

#include <iostream>
#include <array>

using namespace std;

int main()
{
    // 创建一个包含 5 个 int 的 array,并初始化
    std::array<int, 5> arr = {10, 20, 30, 40, 50};

    // 用下标访问
    std::cout << "arr[0] = " << arr[0] << "\n";
    std::cout << "arr[4] = " << arr[4] << "\n";

    // 用 size() 获取大小
    std::cout << "size = " << arr.size() << "\n";

    return 0;
}

Running result:

arr[0] = 10
arr[4] = 50
size = 5

7.2.Example 2: Building on Example 1, use at() for safe access and fill() for filling

#include <iostream>
#include <array>

using namespace std;

int main()
{
    std::array<int, 5> arr = {10, 20, 30, 40, 50};

    // 用 at() 安全访问
    std::cout << "arr.at(2) = " << arr.at(2) << "\n";

    // 用 fill() 将所有元素设为同一个值
    arr.fill(99);

    std::cout << "after fill: ";
    for (int n : arr)
    {
        std::cout << n << " ";
    }
    std::cout << "\n";

    return 0;
}

Running result:

arr.at(2) = 30
after fill: 99 99 99 99 99 

7.3.Example 3: Based on Example 2, compare passing parameters for C arrays and std::array

#include <iostream>
#include <array>

using namespace std;

// C 风格:数组退化为指针,丢失大小信息
void print_c_array(int* arr, int size)
{
    std::cout << "C array: ";
    for (int i = 0; i < size; ++i)
    {
        std::cout << arr[i] << " ";
    }
    std::cout << "\n";
}

// std::array:大小信息不丢失
void print_std_array(const std::array<int, 5>& arr)
{
    std::cout << "std::array: ";
    for (int n : arr)
    {
        std::cout << n << " ";
    }
    std::cout << "\n";
    std::cout << "size from inside function = " << arr.size() << "\n";
}

int main()
{
    std::array<int, 5> arr = {1, 2, 3, 4, 5};

    // C 风格:需要额外传大小
    print_c_array(arr.data(), arr.size());

    // std::array:自带大小信息
    print_std_array(arr);

    return 0;
}

Running result:

C array: 1 2 3 4 5 
std::array: 1 2 3 4 5 
size from inside function = 5

8.Operation result

See the "run results" for each example above.

9.Key syntax explanation in the example

Example What was discussed Newly introduced syntax Why it is written this way Notes
Example 1 Creating an array and basic access std::array<T, N>、size() The array size is a compile-time constant,size() returns a fixed value The size must be a compile-time constant; you cannot pass a variable
Example 2 Safe access with at() and filling with fill() at()、fill() at()An out-of-bounds access throws an exception;fill() convenient for batch assignment fill()Assigns the same value to all elements
Example 3 Comparing C arrays and array parameter passing data()、const std::array<int,5>& When an array is passed as a parameter, size information is not lost The array size is part of the type; different sizes are different types

10.When is the difference between array and vector obvious?

If you are just storing 5 integers,array and vector both seem usable. But in engineering, the difference mainly lies in "whether the size is fixed" and "whether dynamic expansion is needed":

Scenario Recommendation Reason
Three-axis IMU data {x, y, z} std::array<double, 3> The size is always 3, no expansion needed
Fixed-length PID parameters {kp, ki, kd} std::array<double, 3> The size is known at compile time, and the semantics are clear
Read a batch of sensor points at runtime std::vector<Point> The number of points is only known at runtime
The user enters an arbitrary amount of data std::vector<T> Need push_back dynamic growth

array More like a "fixed array with an STL interface,"vector More like a "variable-length array." Don't use it everywhere just because array is more lightweight: whenever the number of elements is only known at runtime, you should use vector.

10.1.Example 4: Fixed three-axis data is more suitable for an array

#include <array>
#include <iostream>

using namespace std;

// std::array 是固定长度数组,长度在编译期就确定。
double norm3(const std::array<double, 3>& v)
{
    return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
}

int main()
{
    // 程序从 main 函数开始执行,下面的语句会按顺序运行。
    std::array<double, 3> accel = {0.1, 0.2, 9.8};

    std::cout << "accel size = " << accel.size() << "\n";
    std::cout << "squared norm = " << norm3(accel) << "\n";

    return 0;
}

Running result:

accel size = 3
squared norm = 96.09

In this example, the three-axis data must be exactly 3 values. Use std::array<double, 3> to encode this constraint into the type; if you mistakenly pass std::array<double, 2>, a compile-time error will occur.

11.Common Errors

Error 1: Using a variable to specify the array size

int n = 5;
std::array<int, n> arr;  // ❌ 编译错误!n 必须是编译期常量

Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.

Correct approach: use the constexpr constant, or switch to std::vector.

Error 2: Accessing without initialization

std::array<int, 5> arr;   // 值未定义(栈上的垃圾值)
std::cout << arr[0];      // ❌ 未定义行为

Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.

Correct approach: use {} to initialize or fill().

Error 3: Assigning arrays of different sizes to each other

std::array<int, 3> a = {1, 2, 3};
std::array<int, 5> b = a;  // ❌ 编译错误!类型不同

Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.

Correct approach:std::array<int,3> and std::array<int,5> are different types and cannot be assigned to each other.

12.Usage Recommendations

  1. For compile-time known sizes, use arrayIf the size is known at compile time, using std::array is lighter than std::vector (no heap allocation).
  2. Replacing C arrays: wherever std::array can be used, don't use int arr[N].
  3. Note the size when passing parametersThe size of std::array<T, N> is part of the type; the function signature must specify N.
  4. AssignableUnlike C arrays, std::array can be assigned as a whole using = (of the same type).

13.Summary

  • std::array<T, N>Encapsulates a fixed-size array whose size is determined at compile time.
  • Has the standard interface of STL containers (size() , at() , iterators, etc.).
  • Can be assigned as a whole, and does not decay to a pointer when passed to a function, so size information is not lost.
  • Suitable for scenarios where the size is known at compile time, and is more lightweight than vector.