1

Hi I am trying to understand the difference between passing a 2d array of type char VS type int to a function as a double-pointer func(int **ptr) parameter. The problem is that it behaves differently. Below I will show two examples for type char and int using PythonTutor for C.

I looked at the whole internet and asked some friends but couldn't find an answer to the behavior.

Example with type char: int func(char **arr)

{
  printf("%d", **arr);  
}
int main() 
{
  char *arr[] = {"char1","char2"};
  return 0;
}

Example with type int:

int func(int **arr)
{
  printf("%d", **arr);  
}
int main() 
{
  int *arr[] = {{1,3},{4,5,6}};
  return 0;
}

One thing to note is that is not important what the func body is doing with the double-pointer passed to it, the problem i am trying to understand is why the double-pointer in the case of 2D char array is pointing to a pointer to integer while the 2D int array is not pointing to the integers within the arrays?

Below is the visualization from pythontutor for both cases.

Example with type char 2D array: http://pythontutor.com/c.html#mode=display

Example with type int 2D array: http://pythontutor.com/c.html#mode=display

Also provide snapshot of the final result:

Example with type char 2D array:

enter image description here

Example with type int 2D array:

enter image description here

Alonso
  • 43
  • 1
  • 8
  • 1
    `int *arr[]` is not a 2D array, it is an *array-of-pointers-to-int*. `int arr[x][y]` with `x & y` are integer literals creates a 2D array. (which on access will be converted to a pointer to the first element (which is a pointer the first 1D array, e.g. *a pointer to array of int[y]*) which is not the same as `int**` (which is simply *a pointer to pointer to int*). – David C. Rankin Nov 06 '19 at 06:44
  • @David Rankin so int *arr[] is not 2D but char array is? – Alonso Nov 06 '19 at 07:00
  • 1
    `type *arr[]` is an *array of pointers*. What follows, e.g. `char *arr[] = {"one", "two"};` must be pointers. For `int *arr[];` you would need for instance `int a[] = {1, 2, 3);` and `int b[] = {3, 4, 5};`, then `int *arr[] = {a, b};` as both `a` and `b` will be converted to pointers on access. [C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)](http://port70.net/~nsz/c/c11/n1570.html#6.3.2.1p3). Also a 2D array is actually an array of 1D arrays. You can represent as `int arr[x][y];` or `int (*arr)[y];` So `type (*arr)[y];` is a *pointer to array*. – David C. Rankin Nov 06 '19 at 07:03
  • 1
    This answer may help further [Converting array of pointers to double pointer](https://stackoverflow.com/questions/57839278/converting-array-of-pointers-to-double-pointer/57839593#57839593). There are many more duplicates, some better than others, unfortunately the SO "Related" links on the right side of the page do not do a good job finding them. – David C. Rankin Nov 06 '19 at 07:10
  • @DavidRankin-ReinstateMonica That makes more sense, but in the case of an array of pointers int *arr[] what happens with the numbers inside {1,2} and {3, 4}? They are not referenced at all it seems. – Alonso Nov 06 '19 at 07:16
  • 1
    Have a look at [what is the difference between *pt in int (*pt)[2\] and pt in int *pt?](https://stackoverflow.com/questions/58151924/what-is-the-difference-between-pt-in-int-pt2-and-pt-in-int-pt), the answers there may be more instructive. There are still more complete answers I'm looking for, but that question is good. – David C. Rankin Nov 06 '19 at 07:17
  • 1
    Here is one more that will help (read the comments too) [Processing the columns of a multidimensional array in C](https://stackoverflow.com/questions/58497885/processing-the-columns-of-a-multidimensional-array-in-c). You can find many more questions and answers, but there isn't one specific search likely to find them all given how different problems are described in the original title of the question. The problems all boil down to understanding how *array / pointer* conversion works. That's section 6.3.2.1 linked earlier. It's worth getting a handle on now, it will save you hours later. – David C. Rankin Nov 06 '19 at 07:45
  • @DavidRankin-ReinstateMonica thanks for all the links will make sure to check them all. The main confusion for me was between 2D array initialization and the array of pointers. Another thing that I don't understand and maybe the links you provided have it, why is the `char` array converting directly into pointers vs the `int` array which needs variables `a` and `b` to point to the two integer arrays? – Alonso Nov 06 '19 at 12:45
  • 1
    `int *arr[] = {{1,3},{4,5,6}};` does not initialize an array of pointers. e.g. `{1, 2}` on its own is not a pointer. You can make it a pointer using a *compound literal*, (c99+) e.g. `int *arr[] = { (int[]){1,2}, (int[]){3,4,5} };` and it you want an exercise using the various pointer/array notations to access all elements, you can do `printf ("%d %d %d %d %d\n", **arr, (*arr)[1], *arr[1], *(*(arr + 1) + 1), arr[1][2]);`See [6.5.2.5 Compound literals](http://port70.net/~nsz/c/c11/n1570.html#6.5.2.5) for further information on that type of initialization. – David C. Rankin Nov 06 '19 at 16:26

0 Answers0