Passing Arrays
Lesson outline
Array Decay Pitfalls
When arrays are passed to functions by value-like syntax, they decay to pointers and lose their extent (size) information. Consequences:
- Size must be passed separately (or recovered via another mechanism).
- No bounds checking via
operator[]. - You cannot use range-based
foron the decayed pointer alone (you need a size/range). - Template type deduction loses the array bound unless you pass the array by reference.
Modern Alternatives
Prefer these over C-style array parameters:
| Type | Size Handling | Bounds Checking |
|---|---|---|
| std::array | Fixed at compile-time | Optional via at(); operator[] unchecked |
| std::vector | Dynamic (resizable) | Optional via at(); operator[] unchecked |
| std::span (C++20) | Runtime size (non-owning view) | No built-in checks; use size()/algorithms |
Using std::span for Parameters (C++20)
std::span lets you accept any contiguous sequence (T[N], std::array, std::vector) with size preserved at runtime, without copying.
Preserving Size with References (Templates)
If you cannot use C++20, pass arrays by reference to capture their extent at compile time.
Multidimensional Arrays
Passing multidimensional arrays requires keeping the rightmost bound(s) known to the function.
Prefer references or std::array for fixed sizes.
Common Pitfall: int** is NOT int[][M]
int does not model a contiguous 2D array created as int a[R][C];. Passing a to a function taking int is ill-formed/incorrect because the memory layouts differ. Use one of the correct forms above, or flatten to 1D with manual indexing.