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, usestaticorstd::vector. - Forgetting aggregate initialization:
std::array<int, 3> a;leaves elements uninitialized. Usestd::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 tooperator[]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.