Learning materials

Multidimensional Array

On this page

General Multidimensional Array

  • Multidimensional arrays - arrays of arrays

    int a[10];  // 1d local array
    int a1[2][3];  // 2d local array
    int a2[2][3][4];  // 3d local array
    int **a3;  // pointer of pointer to int, used for 2D dynamic array
    int ***a4;  // pointer of pointer of pointer to int, used for 3D dynamic array
    

Graphviz diagram

int matrix[10][10]; // a local 10 x 10 2D array

Two dimensional array

  • 2d local array

    Example: a local array a1 with 2 rows, 3 columns

    • int a1[2][3];

    • a1 has the pointer part of the array with the int ** type

    • a1 is an array of 2 element, and each element is an array of 3 int

    • memory allocated on stack memory region

    • initialization syntax

      // initialization of 2d array
      // a1[0] is {1, 2, 3}, a1[1] is {4, 5, 6}
      int a1[2][3] = {{1, 2, 3}, {4, 5, 6}};
      int a2[2][3] = {1, 2, 3, 4, 5, 6};
      int a3[][3] = {1, 2, 3, 4, 5, 6};  // first dimension can be inferred
      
  • 2d dynamic array

    Example: a dynamic array dynArr1 with 2 rows, 3 columns

    // declaration
    int **dynArr1;
    
    // allocate memory (on Heap)
    dynArr1 = new int *[2];
    for (int i = 0; i < 2 ; ++i)
      dynArr1[i] = new int[3];
    //now you can access element using array syntax like dynArr1[0][0]
    
    // put values into the array
    for (int i = 0; i < 2 ; ++i)
      for (int j = 0; j < 3; ++j)
        dynArr1[i][j] = i * 3 + j + 1;
    // now dynArr1 is {{1, 2, 3}, {4, 5, 6}}
    
    // release memory
    for (int i = 0; i < 2 ; ++i)
      delete [] dynArr1[i];
    delete [] dynArr1;
    
  • 2d array as a function parameter
    1. pass a 2 x 3 local array

      • Declared like int a1[2][3];
      • Not useful in real projects because of the limitation on dimension
      // ---- wrong ----
      void matrixOp(int matrix[rows][cols], int rows, int cols);
      void matrixOp(int matrix[][], int rows, int cols);
      void matrixOp(int matrix[2][], int rows, int cols);
      
      // ---- correct ----
      // only the first dimension can be empty, use int literals
      // or const variables for other dimensions
      void matrixOp(int matrix[2][3], int rows, int cols);
      void matrixOp(int matrix[][3], int rows, int cols);
      
      // using const variables
      const int ROWS = 2;
      const int COLS = 3;
      void matrixOp(int matrix[ROWS][COLS], int rows, int cols);
      void matrixOp(int matrix[][COLS], int rows, int cols);
      
      // to call
      int a1[2][3] = {{1, 2, 3}, {4, 5, 6}};
      matrixOp(a1, 2, 3)
      
    2. passing a dynamic array, a much nicer solution + declared like int **dyArr1

      // correct version 1
      void matrixOp(int ** matrix, int rows, int cols) {
        for (int i = 0; i < rows ; ++i)
          for (int j = 0; j < cols; ++j)
            cout << matrix[i][j] << " ";  // same syntax as local array
      }
      // correct version 2
      void matrixOp(int *matrix[], int rows, int cols);
      
      // to call the function
      int **dyArr1;
      dyArr1 = new int *[2];
      for (int i = 0; i < 2; ++i) {
        dyArr1[i] = new int[3];
        // initialize values
      }
      matrixOp(dynArr1, 2, 3);
      // for loop delete []
      for (int i = 0; i < 2; ++i)
        delete [] dyArr1[i];
      delete [] dyArr1;
      
  • Returning a Multidimensional array from a function

    Just make a dynamic array and return the pointer:

    int **createMatrix(int rows, int cols, int value);
    
    int **createMatrix(int rows, int cols, int value) {
      int **result;
      result = new int *[rows];
      for (int i = 0; i < rows; ++i) {
        result[i] = new int[cols];
        for (int j = 0; j < cols; ++j)
          result[i][j] = value;
      }
      return result;
    }
    
    int main() {
      int **matrix = createMatrix(3, 5, 1);
    
      // work on the matrix
    
      // release memory
      for (int i = 0; i < rows; ++i)
        delete [] matrix[i];
      delete [] matrix;
    }
    

Pitfalls

// bad local array declaration
int arr[rows][cols];  // rows and cols are not compilation-time constants
int arr[][];
int arr[2][];
int arr[][3];

// bad dynamic array related
int **arr = new int[2][3];  // cannot use more than one pair of [] with new
delete arr;  // missing []
delete [2][3] arr;
delete [][] arr;
delete arr[2][3];

// bad function declarations that take local array parameters
void func1(int arr[][], int rows, int cols);
void func1(int arr[2][], int rows, int cols);
void func1(int arr[rows][cols], int rows, int cols);


// bad function declarations that take dynamic array parameters
void func1(int *arr[], int rows, int cols);