2

Suppose I have a 2D array - int Array[2][2]; I know that I can implement an array having 4 elements with 2 in each row [1 row makes an array]. I want to know if **Arr - A pointer to a pointer can be used as a 2D array.

  • Yes, you can do that, it's completely okay. – Akshay Saambram Jul 05 '21 at 06:20
  • 3
    You can create a [*jagged array*](https://en.wikipedia.org/wiki/Jagged_array) using pointers to pointers. But you can't generally get a pointer to a pointer for an array of arrays, [they are simply not the same](https://stackoverflow.com/questions/18440205/casting-void-to-2d-array-of-int-c/18440456#18440456). – Some programmer dude Jul 05 '21 at 06:21
  • Yes and No. Yes, basically. No, not if you are not very careful with having a malloc and a free for each pointer and on each level of pointer-to-pointer. – Yunnosch Jul 05 '21 at 06:27
  • @Someprogrammerdude In case of pointer to pointer, doesn't *(Array + I) point to the ith row elements? – Rohan Gurumurthy Jul 05 '21 at 06:30
  • Note: Given `int array[2][2]` you cannot `int ** pointer = array` or pass `array` to a function expecting an `int **` argument. `int array[2][2]` decays to `int *[2]`, a pointer to arrays of 2 elements, not to a pointer to a pointer. – user4581301 Jul 05 '21 at 06:31
  • Remember that `*(Array + I)` is *exactly* the same as `Array[I]`. And each member of your `Array` is in turn an array. Which can *decay* to a pointer. But it's not in itself a pointer. The type of `Array[I]` (for any valid index `I`) is `int[2]`. If you follow my link you can see the difference. – Some programmer dude Jul 05 '21 at 06:35
  • @user4581301 The array decays to `int (*)[2]` which is quite different from `int *[2]`. Your text is correct though, just not the type. – Some programmer dude Jul 05 '21 at 06:37
  • Apologies. Yes. Left out the brackets – user4581301 Jul 05 '21 at 06:38
  • For C++ code consider using [`std::array`](https://en.cppreference.com/w/cpp/container/array) when you need tp pass arrays around. It makes life easier, especially when you have multiple dimensions. Often it is even better to make yourself an alias to hide the otherwise cumbersome syntax. `using matrix = std::array, 2>;` allows you to write `matrix array`. – user4581301 Jul 05 '21 at 06:45
  • Duplicate: [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – Lundin Jul 05 '21 at 06:47

2 Answers2

6

Note: This answer is relevant for the C tag only. In C++ it's different and also something you would seldom (like nearly never) do.

I want to know if **Arr - A pointer to a pointer can be used as a 2D array.

Yes, it's called jagged array. You do it like:

int rows = 2;
int cols = 2;
int** arr = malloc(rows * sizeof *arr);
for (int i=0; i<rows; ++i)
{
    arr[i] = malloc(cols * sizeof *arr[i]);
}

Now you can access, e.g. arr[1][0]

When done with the array, you need to free it. It's the "reverse" operation of your malloc. Like:

for (int i=0; i<rows; ++i)
{
    free(arr[i]);
}
free(arr);

Another alternative is to use a pointer to an array of cols int. Like

int (*arr)[cols] = malloc(rows * sizeof *arr);

... use arr, e.g. arr[1][0] = 42; ...

free(arr);

The benefit of the second code is that it is much simpler (less code, fewer calls of malloc and free resulting in better performance).

Jagged arrays are good in cases where you need a variable number of columns in the rows. For instance if some rows only require 10 integers and other rows require 10.000 integers, you can save memory by only allocating the number of columns actually needed for the specific row (instead of always allocating the MAX number of columns for all rows). Further, it's good if you need to change the number of columns at runtime (using, e.g. realloc).

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
0

Yes, it can be used. As there is already an answer, which explicitly mentions that It is for C.

You can use create a two-indirection array in C++.

    int size = 5;
    int** array = new int*[size]; // Array of pointers to array of ints
    for (int i = 0; i < size;++i){
       array[i] = new int[size];
     }

Do not forget to free the memory with the delete [] operator.

    for(int i = 0; i < size; ++i){
       delete [] array[i];
    }
    delete[] array;

If you are using C++, you will probably never use this, you should consider using vector or array as they make your code more verbose, and manage the memory themselves. And more cache-friendly.

foragerDev
  • 1,307
  • 1
  • 9
  • 22