Tutorials Logic, IN info@tutorialslogic.com

C++ Arrays, std::array, and std::vector

Contiguous Collections

An array stores same-type elements contiguously and addresses them with zero-based indexes. A raw array has a compile-time extent that is easily lost when passed to a function; std::array preserves fixed-size container behavior, while std::vector owns a dynamically sized contiguous buffer.

After this lesson you can choose a fixed or dynamic container, avoid one-past-the-end access, explain vector reallocation, traverse a grid, and build a prefix-sum table for repeated range totals.

Bounds and Defensive Access

The [] operator is fast but does not check bounds. vector::at checks bounds and throws an exception when the index is invalid. Beginners can use at while learning; experienced code often uses tests and invariants to keep [] safe.

  • Know valid indexes before access.
  • Use at for defensive learning examples.
  • Do not ignore empty-vector cases.

2D Arrays and Grids

Arrays can represent matrices, boards, tables, and images. In modern C++, vector<vector<int>> is flexible, while fixed arrays or flat vectors can be faster for known dimensions.

  • Track row and column separately.
  • Validate both dimensions.
  • Use meaningful names such as rows and cols.

Prefix Sum Pattern

Prefix sums preprocess an array so repeated range-sum queries become fast. This pattern turns O(n) per query into O(1) per query after O(n) setup.

  • Build prefix[i + 1] from prefix[i].
  • Use prefix[right + 1] - prefix[left].
  • Test first and last ranges.

Run the Collection Examples

Compile each example, test empty and one-element inputs, and inspect how the chosen container reports its size.

Vector Traversal and Update

Vector Traversal and Update
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> prices = {100, 250, 80};

    for (int& price : prices) {
        price += 10;
    }

    for (int price : prices) {
        cout << price << ' ';
    }
}

Safe Function Parameter

Safe Function Parameter
#include <iostream>
#include <vector>
using namespace std;

int maxValue(const vector<int>& values) {
    int best = values[0];
    for (int value : values) {
        if (value > best) best = value;
    }
    return best;
}

int main() {
    vector<int> marks = {71, 95, 84};
    cout << maxValue(marks) << '\n';
}

Prefix Sum Range Query

Prefix Sum Range Query
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> nums = {2, 4, 6, 8};
    vector<int> prefix(nums.size() + 1, 0);

    for (int i = 0; i < (int)nums.size(); i++) {
        prefix[i + 1] = prefix[i] + nums[i];
    }

    int left = 1, right = 3;
    cout << prefix[right + 1] - prefix[left] << '\n';
}

2D Grid Traversal

2D Grid Traversal
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<vector<int>> grid = {{1, 2}, {3, 4}};

    for (int row = 0; row < (int)grid.size(); row++) {
        for (int col = 0; col < (int)grid[row].size(); col++) {
            cout << grid[row][col] << ' ';
        }
    }
}
Before you move on

Array Safety Review

5 checks
  • Use std::array for a fixed count and std::vector for runtime growth.
  • Keep indexes strictly below size.
  • Use at() where checked access helps diagnose input errors.
  • Expect vector growth to invalidate some references and iterators.
  • Test grids with one row, one column, and uneven external input.

Array Questions

Most array parameters decay to pointers, so <code>sizeof</code> inside the function measures the pointer rather than the original array. Pass a <code>std::span</code>, accept the array by reference with its size as a template parameter, or use <code>std::array</code>/<code>std::vector</code>.

When a vector outgrows its capacity, it reallocates its contiguous storage and moves the elements. Pointers, references, and iterators into the old allocation then dangle. Call <code>reserve</code> when a useful upper bound is known, or avoid retaining element addresses across operations that may change capacity.

Use <code>std::array</code> when the element count is fixed at compile time and value semantics are useful. Choose <code>std::vector</code> when the count is determined at runtime or must grow. Both are contiguous and work with standard algorithms; unlike a raw array, <code>std::array</code> also preserves its size during assignment and function calls.

Next Step
Next Practice

Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.