Dynamic Arrays using std::vector

Using Vector for a 2D Grid

How can I use std::vector to implement a simple 2D grid or matrix?

Abstract art representing computer programming

Using std::vector to implement a 2D grid or matrix is a common and efficient way to handle two-dimensional data in C++. There are primarily two approaches: using a vector of vectors, or using a single vector with custom indexing.

Approach 1: Vector of Vectors

This is the most straightforward approach, where we create a vector of vector elements:

#include <iostream>
#include <vector>

class Grid {
private:
  std::vector<std::vector<int>> data;
  size_t rows, cols;

public:
  Grid(size_t r, size_t c)
    : rows(r), cols(c),
      data(r, std::vector<int>(c, 0)){}

  int& at(size_t r, size_t c){
    return data[r][c];
  }

  const int& at(size_t r, size_t c) const{
    return data[r][c];
  }

  void print() const{
    for (const auto& row : data) {
      for (int val : row) {
        std::cout << val << ' ';
      }
      std::cout << '\n';
    }
  }
};

int main(){
  Grid grid(3, 4);

  // Set some values
  grid.at(0, 0) = 1;
  grid.at(1, 2) = 5;
  grid.at(2, 3) = 9;

  // Print the grid
  grid.print();
}
1 0 0 0
0 0 5 0
0 0 0 9

This approach is intuitive and allows for rows of different lengths if needed. However, it may have slightly more overhead due to multiple allocations.

Approach 2: Single Vector with Custom Indexing

This approach uses a single vector to store all elements, which can be more efficient:

#include <iostream>
#include <vector>

class Grid {
private:
  std::vector<int> data;
  size_t rows, cols;

public:
  Grid(size_t r, size_t c)
    : rows(r), cols(c), data(r * c, 0){}

  int& at(size_t r, size_t c){
    return data[r * cols + c];
  }

  const int& at(size_t r, size_t c) const{
    return data[r * cols + c];
  }

  void print() const{
    for (size_t i = 0; i < rows; ++i) {
      for (size_t j = 0; j < cols; ++j) {
        std::cout << at(i, j) << ' ';
      }
      std::cout << '\n';
    }
  }
};

int main(){
  Grid grid(3, 4);

  // Set some values
  grid.at(0, 0) = 1;
  grid.at(1, 2) = 5;
  grid.at(2, 3) = 9;

  // Print the grid
  grid.print();
}
1 0 0 0
0 0 5 0
0 0 0 9

This approach uses a single allocation and can be more cache-friendly, potentially offering better performance for large grids.

Advanced Features

You can extend either approach with more advanced features:

Range Checking

Add bounds checking in the at() function:

int& at(size_t r, size_t c){
  if (r >= rows || c >= cols) {
    throw std::out_of_range(
      "Grid indices out of range");
  }
  return data[r * cols + c];
}

Iterators

Implement custom iterators for row-wise or column-wise traversal.

Resizing

Add functions to resize the grid:

void resize(size_t new_rows, size_t new_cols){
  std::vector<int> new_data(
    new_rows * new_cols, 0);
  for (size_t i = 0; i <
       std::min(rows, new_rows); ++i) {
    for (size_t j = 0; j <
         std::min(cols, new_cols); ++j) {
      new_data[i * new_cols + j] = at(i, j);
    }
  }
  data = std::move(new_data);
  rows = new_rows;
  cols = new_cols;
}

Operations

Implement mathematical operations like matrix addition or multiplication.

Remember, the choice between these approaches depends on your specific use case. The vector of vectors is more flexible but might be slightly slower, while the single vector approach is generally faster but less flexible for non-rectangular grids.

Answers to questions are automatically generated and may not have been reviewed.

3D art showing a progammer setting up a development environment
Part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access

This course includes:

  • 57 Lessons
  • Over 200 Quiz Questions
  • 95% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved