Multidimensional Array

General Multidimensional Array

  • Multidimensional arrays - arrays of arrays

    1int a[10];  // 1d local array
    2int a1[2][3];  // 2d local array
    3int a2[2][3][4];  // 3d local array
    4int **a3;  // pointer of pointer to int, used for 2D dynamic array
    5int ***a4;  // pointer of pointer of pointer to int, used for 3D dynamic array
    
digraph G {
  nodesep=.05;
  rankdir=LR;
  matrix[shape=box,height=0.1];
  node[shape=record,width=0.1,height=0.1];
  first[label="<f0>|<f1>|<f2>|<f3>|<f4>|<f5>|<f6>|<f7>|<f8>|<f9>"];
  matrix -> first:f0;

  sec0[label="{<s0>||||||||}"];
  sec1[label="{<s0>||||||||}"];
  sec2[label="{<s0>||||||||}"];
  sec3[label="{<s0>||||||||}"];
  sec4[label="{<s0>||||||||}"];
  sec5[label="{<s0>||||||||}"];
  sec6[label="{<s0>||||||||}"];
  sec7[label="{<s0>||||||||}"];
  sec8[label="{<s0>||||||||}"];
  sec9[label="{<s0>||||||||}"];

  first:f0 -> sec0:s0:w;
  first:f1 -> sec1:s0:w;
  first:f2 -> sec2:s0:w;
  first:f3 -> sec3:s0:w;
  first:f4 -> sec4:s0:w;
  first:f5 -> sec5:s0:w;
  first:f6 -> sec6:s0:w;
  first:f7 -> sec7:s0:w;
  first:f8 -> sec8:s0:w;
  first:f9 -> sec9:s0:w;
}

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

      1// initialization of 2d array
      2// a1[0] is {1, 2, 3}, a1[1] is {4, 5, 6}
      3int a1[2][3] = {{1, 2, 3}, {4, 5, 6}};
      4int a2[2][3] = {1, 2, 3, 4, 5, 6};
      5int 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

     1// declaration
     2int **dynArr1;
     3
     4// allocate memory (on Heap)
     5dynArr1 = new int *[2];
     6for (int i = 0; i < 2 ; ++i)
     7  dynArr1[i] = new int[3];
     8//now you can access element using array syntax like dynArr1[0][0]
     9
    10// put values into the array
    11for (int i = 0; i < 2 ; ++i)
    12  for (int j = 0; j < 3; ++j)
    13    dynArr1[i][j] = i * 3 + j + 1;
    14// now dynArr1 is {{1, 2, 3}, {4, 5, 6}}
    15
    16// release memory
    17for (int i = 0; i < 2 ; ++i)
    18  delete [] dynArr1[i];
    19delete [] 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

       1// ---- wrong ----
       2void matrixOp(int matrix[rows][cols], int rows, int cols);
       3void matrixOp(int matrix[][], int rows, int cols);
       4void matrixOp(int matrix[2][], int rows, int cols);
       5
       6// ---- correct ----
       7// only the first dimension can be empty, use int literals
       8// or const variables for other dimensions
       9void matrixOp(int matrix[2][3], int rows, int cols);
      10void matrixOp(int matrix[][3], int rows, int cols);
      11
      12// using const variables
      13const int ROWS = 2;
      14const int COLS = 3;
      15void matrixOp(int matrix[ROWS][COLS], int rows, int cols);
      16void matrixOp(int matrix[][COLS], int rows, int cols);
      17
      18// to call
      19int a1[2][3] = {{1, 2, 3}, {4, 5, 6}};
      20matrixOp(a1, 2, 3)
      
    2. passing a dynamic array, a much nicer solution + declared like int **dyArr1

       1// correct version 1
       2void matrixOp(int ** matrix, int rows, int cols) {
       3  for (int i = 0; i < rows ; ++i)
       4    for (int j = 0; j < cols; ++j)
       5      cout << matrix[i][j] << " ";  // same syntax as local array
       6}
       7// correct version 2
       8void matrixOp(int *matrix[], int rows, int cols);
       9
      10// to call the function
      11int **dyArr1;
      12dyArr1 = new int *[2];
      13for (int i = 0; i < 2; ++i) {
      14  dyArr1[i] = new int[3];
      15  // initialize values
      16}
      17matrixOp(dynArr1, 2, 3);
      18// for loop delete []
      19for (int i = 0; i < 2; ++i)
      20  delete [] dyArr1[i];
      21delete [] dyArr1;
      
  • Returning a Multidimensional array from a function

    Just make a dynamic array and return the pointer:

     1int **createMatrix(int rows, int cols, int value);
     2
     3int **createMatrix(int rows, int cols, int value) {
     4  int **result;
     5  result = new int *[rows];
     6  for (int i = 0; i < rows; ++i) {
     7    result[i] = new int[cols];
     8    for (int j = 0; j < cols; ++j)
     9      result[i][j] = value;
    10  }
    11  return result;
    12}
    13
    14int main() {
    15  int **matrix = createMatrix(3, 5, 1);
    16
    17  // work on the matrix
    18
    19  // release memory
    20  for (int i = 0; i < rows; ++i)
    21    delete [] matrix[i];
    22  delete [] matrix;
    23}
    

Warning

This is the only option to return an array! Never return a local array!

Warning

Never forget to delete dynamic array(s)!

Pitfalls

 1// bad local array declaration
 2int arr[rows][cols];  // rows and cols are not compilation-time constants
 3int arr[][];
 4int arr[2][];
 5int arr[][3];
 6
 7// bad dynamic array related
 8int **arr = new int[2][3];  // cannot use more than one pair of [] with new
 9delete arr;  // missing []
10delete [2][3] arr;
11delete [][] arr;
12delete arr[2][3];
13
14// bad function declarations that take local array parameters
15void func1(int arr[][], int rows, int cols);
16void func1(int arr[2][], int rows, int cols);
17void func1(int arr[rows][cols], int rows, int cols);
18
19
20// bad function declarations that take dynamic array parameters
21void func1(int *arr[], int rows, int cols);