printing 2d dynamic array + pointers

the first function is given by the professor and should work properly, but i get seg fault.
the second function outputs memory address instead of the element.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
   void print_2darray_dynamic_subscript(int ** twoDD, int row, int col)
  // print array using subscripts
  {
    for (int i = 0; i < row; i++) {
      for (int j = 0; j < col; j++)
				//this gives me segfault
        // cout << twoDD[i][j] << " ";
      cout << endl;
    }
    cout << endl;
  }

  void print_2darray_dynamic_pointer(int ** twoDD, int row, int col)
  // print array using pointer arithmetic
  {
    for (int i = 0; i < row; i++) {
      for (int j = 0; j < col; j++) {
        // our dynamic 2d array is an array of int pointers
        // each component in the array itself points to an array of ints
        // dynamic array rows are not contiguous in memory

        // to compute the offset using pointer math
        // offset from twoDD: move to the correct row, add #row (i), dereference to obtain pointer to row
        // next, add #col (j), result: pointer to array element
        // ...

				//the output points to the address instead of the actual element.
        cout << (twoDD + i * col + j) << " ";
      }
      cout << endl;
    }
    cout << endl;
  }


here's the complete code: https://repl.it/@bondat/hw8
lines 73-105

ps i also don't understand how i can delete each row from the dynamic 2d array (lines 389-393)

1
2
3
4
5
6
// [5.4] delete individual rows (i.e. rows are int arrays, use delete [])
  //for(// ...) // ...
  // i came about the following code somewhere but it gives me an error.
  //	for(int i=0; i<hw08::TIC_TAC_TOE_SIZE; i++){
  //		delete[] p_p_tictactoe[i];
  //	} 


i'd really appreciate it if you'd rather go over the whole homework bc i still have difficulty understanding pointers in general.
int ** p_p_tictactoe = new int * [hw08::TIC_TAC_TOE_SIZE];
This is created an array of TIC_TAC_TOE_SIZE number of pointer (int*). But those pointers themselves still point to junk (they aren't initialized).

You want something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Example program
int main()
{
    const int Size = 3;
    int** arr = new int*[Size]; // create "Size" int-pointers
    
    for (int i = 0; i < Size; i++)
    {
        arr[i] = new int[Size]; // set each pointer to point to a new array of ints
    }
    
    // use
    arr[0][1] = 42;
    
    // clean up
    for (int i = 0; i < Size; i++)
    {
        delete[] arr[i];   
    }
    delete[] arr;
}


_______________________________________

cout << (twoDD + i * col + j) << " ";
twoDD is some sort of pointer, so printing a pointer normally just prints the value of the pointer (which is a memory address). i, col, and j are just offsets in this manner, so the end result is still it printing some random memory address.

arr[i] is equivalent to *(arr + i)
So, arr[i][j] is equivalent to *(*(arr + i) + j)
Last edited on
2D arrays by pointer are a bloody mess and a half. You have to cast the 2D array to a 1D array when passed to your function and then parse out the dimensions using simulated 2D in 1D fashion inside the function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

void print2Darray_pointer(int *arr, int row, int col);

int main()
{
   const int row { 3 };
   const int col { 3 };

   int arr[row][col] { { 1, 2, 3},
                       { 4, 5, 6},
                       { 7, 8, 9} };

   print2Darray_pointer(reinterpret_cast<int*> (arr), row, col);
}

void print2Darray_pointer(int* arr, int r, int c)
{
   for (int row { }; row < r; row++)
   {
      for (int col { }; col < c; col++)
      {
         std::cout << *((arr + row * c) + col) << ' ';
      }
      std::cout << '\n';
   }
}


Using subscripts is almost as bad with 2D arrays, you have to specify the second or both subscript sizes in the function parameter list.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

void print2Darray_subscript(int arr[][3], int row, int col);

int main()
{
   const int row { 3 };
   const int col { 3 };

   int arr[row][col] { { 1, 2, 3},
                       { 4, 5, 6},
                       { 7, 8, 9} };

   print2Darray_subscript(arr, row, col);
}

void print2Darray_subscript(int arr[][3], int r, int c)
{
   for (int row { }; row < r; row++)
   {
      for (int col { }; col < c; col++)
      {
         std::cout << arr[row][col] << ' ';
      }
      std::cout << '\n';
   }
}

Both subscript used: void print2Darray_subscript(int arr[3][3], int row, int col);

Using 2D pointers does allow for dynamic sized arrays. Using subscripts at compile time you are required to declare at least one of the array's dimensions. Dynamic sized 2D arrays don't really work with passing arrays as subscripts.

Personally when dealing with true 2D containers I prefer using std::vector.
thanks, people! those mini-lectures actually worked and were easy to understand! i really just have to wrap my mind around these concepts to have a better understanding!!

I'll be back should i come up with another question!!!
Topic archived. No new replies allowed.