C/C++ Arena

Step 4 of 6

2D vectors

A vector can hold anything, including other vectors. A vector of vectors gives you a 2D grid whose size is decided at run time, without any manual memory management:

#include <iostream>
#include <vector>

int main() {
    int rows = 3, cols = 4;
    std::vector<std::vector<int>> grid(rows, std::vector<int>(cols, 0));
    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            grid[r][c] = r * cols + c;
        }
    }
    std::cout << grid[2][3] << " " << grid.size() << "x" << grid[0].size() << "\n";
    int diagonal = 0;
    for (int i = 0; i < rows; i++) diagonal += grid[i][i];
    std::cout << diagonal << "\n";
}
11 3x4
15

Reading the declaration

std::vector<std::vector<int>> grid(rows, std::vector<int>(cols, 0)) means: rows copies of "a vector of cols zeros". Each row is its own independent vector.

Sizes

Building a result of a different shape

When the output has a different shape from the input (like swapping rows and columns), create the output grid with the new dimensions first, then fill it with nested loops, reading from the input's [r][c] and writing to the output's corresponding position.

Compared with the C version (an array of row pointers with a malloc per row and careful freeing), this is shorter, can't leak, and copies correctly. The trade-off is that rows are separate allocations; performance-critical code sometimes uses one flat vector of rows * cols elements instead.

Your turn: write std::vector<std::vector<int>> transpose(const std::vector<std::vector<int>>& m) that swaps rows and columns. A 2x3 matrix becomes 3x2. You can assume every row has the same length and there's at least one row.

Previous: Insert and erase Next: string search and substrings