ReviseAlgo Logo

Arrays and Strings

std::array

Fixed-size, STL-compatible array with no overhead over C arrays

Interview: The modern replacement for C arrays — demonstrates knowledge of zero-cost abstractions

std::array

std::array<T, N> (C++11, <array>) is a zero-overhead wrapper around a C-style array that adds STL compatibility — iterators, algorithms, size(), and bounds-checked access — without any runtime cost. Unlike C arrays, it doesn't decay to a pointer when passed to functions, preserving size information.

Advantages Over C Arrays

No Decay

Passed to functions by value or reference — size is preserved. No information loss.

STL Integration

Works with std::sort, std::find, range-based for, and all standard algorithms out of the box.

Bounds Checking

at(i) throws std::out_of_range on bad index. operator[] is unchecked (fast) — your choice.

Value Semantics

Can be copied and assigned naturally. arr1 = arr2 copies all elements — cleaner than memcpy.

Compile-Time Size

The size N is a compile-time constant — size() is constexpr. This enables using std::array in compile-time contexts (constexpr computations, template parameters). The entire array lives on the stack — no heap allocation.

vs std::vector

Use std::array when the size is fixed at compile time — it's stack-allocated, constexpr-capable, and has zero overhead. Use std::vector when size varies at runtime. Never use raw C arrays in modern C++.

Interview Corner

Q: What is the difference between std::array, C-style array, and std::vector?

A: C-style array: stack-allocated, fixed-size, no bounds checking, decays to pointer, no STL integration. std::array: stack-allocated, fixed-size at compile time, STL-compatible, no decay, optional bounds checking, zero overhead. std::vector: heap-allocated, dynamic-size, STL-compatible, size tracked, bounds-checked via at(). Use array when size is known at compile time, vector for runtime-dynamic sizes, and avoid raw C arrays entirely.

Q: Can you use std::array in constexpr context?

A: Yes. Since C++17, many std::array operations (construction, element access, size()) are constexpr, enabling compile-time array computations. Example: constexpr std::array<int,3> primes{2,3,5}; static_assert(primes[2]==5); — fully evaluated at compile time with zero runtime cost.

Common Pitfalls

  • Large arrays on the stack: std::array lives entirely on the stack. Declaring std::array<int, 1000000> allocates 4MB on the stack — likely a stack overflow. For large fixed-size arrays, use static or std::vector.
  • Forgetting aggregate initialization: std::array<int, 3> a; leaves elements uninitialized. Use std::array<int, 3> a{} (zero-initialize) or provide explicit values.

Best Practices

  • Replace all raw C-style arrays in new code with std::array — identical performance, strictly safer.
  • Use at() during development and debugging for bounds checking; switch to operator[] only in verified hot paths.
  • Use CTAD (C++17 Class Template Argument Deduction): std::array a{1, 2, 3}; — the type and size are deduced automatically.