Pawan Nirpal
Pawan Nirpal

Reputation: 610

What does it mean to pass an array of pointers in C?

I am struggling with pointers concept of C, precisely with Array of pointers. See the below program for reference.

#include <stdio.h> 

int a1[] = {6,7,8,18,34,67};
int a2[] = {23,56,28,29};
int a3[] = {-12,27,-31};
int *x[] = {a1,a2,a3};

void print (int *a[]){
  printf ("%d",a[0][2]);
  printf ("%d",*a[2]);
  printf ("%d",*++a[0]);
  printf ("%d",*(++a)[0]);
  printf ("%d",a[-1][1]);
 
}

void main (){ 
  print (x);
}

what I don't understand is, if we are passing int *a[] as an array of pointers, it should be an array after all right ? but I'm being told that here a is only a single pointer variable which acts as an alias to x but according to the syntax a should be an Array, ie. the activation record of print() function should contain an array not merely a pointer variable that holds the base address of x but that's the whole confusion is it a pointer or an array of pointers, the syntax surely suggests that it should be an array of int pointers, I read online but got way more confused, please don't disregard this question by flagging irrelevant.

Upvotes: 1

Views: 158

Answers (1)

Lundin
Lundin

Reputation: 213842

There are two cases where an array "decays" into a pointer to its first item:

  • Whenever the array name is used in (most) expressions, or
  • When a function parameter is declared with array type.

The reason int *x[] = {a1,a2,a3}; works is because those 3 arrays "decay" into a pointer to their first element here. Which in all 3 cases is of type int*, so it is compatible with the element type of the x array.

Then when you define a function such as void print (int *a[]), the compiler silently and implicitly "decays" this array declaration into a pointer to the first element. The first element of an int* [] array is an int* and a pointer to one is int**. So this function is equivalent to void print (int** a);. That's why we can write an empty [] here - the compiler doesn't care about the array size since it will replace the array with a pointer anyway.

And that's also why the multiple levels of indirection a[0][2] works. This is not because a is a 2D array - it isn't. But the first [] does pointer arithmetic on the int** type to get the relevant int* element. And the second does pointer arithmetic on that pointer element in turn, to get to the actual int.

As for the various lines inside that function, it's some sort of artificial school example meant to teach about operator precedence. Hint: postfix operators usually have the highest precedence.

The line a[-1][1] is a bug since it invokes undefined behavior - we shouldn't write programs like that and the reason why is a somewhat advanced topic of it's own. Detailed info here: Is it undefined behaviour to just make a pointer point outside boundaries of an array without dereferencing it?

Upvotes: 2

Related Questions