2

The expression &arrayname + n is supposed to give base address + (number of elements * size of type of elements) * n and it works as expected inside the main() function.

But if I use the same in a different function, it is interpreted differently and produces different output.

Code(32-bit compiler) :

#include <stdio.h>
void arrf(int A[],int n)
{
printf("\n\nInside arrf()");
printf("\n&A ---> %p",A);
for(int i=0;i<n;i++)
    printf("\n&A + %d  ---> %p",i,(&A+i));
}

int main()
{
int A[]={1,2,3,4,5};
int n=5;
printf("Inside main()");
printf("\n&A --->%p",A);
for(int i=0;i<n;i++)
    printf("\n&A + %d  ---> %p",i,(&A+i));
arrf(A,n);
return 0;
}

Sample Ouptut:

Inside main()
&A --->0x7ffed323eac0
&A + 0  ---> 0x7ffed323eac0
&A + 1  ---> 0x7ffed323ead4
&A + 2  ---> 0x7ffed323eae8
&A + 3  ---> 0x7ffed323eafc
&A + 4  ---> 0x7ffed323eb10

Inside arrf()
&A ---> 0x7ffed323eac0
&A + 0  ---> 0x7ffed323ea88
&A + 1  ---> 0x7ffed323ea90
&A + 2  ---> 0x7ffed323ea98
&A + 3  ---> 0x7ffed323eaa0
&A + 4  ---> 0x7ffed323eaa8

Inside main(), &A+1 gives 0x7ffed323eac0 + Hex(5*4*1) = 0x7ffed323eac0 + 0x14 = 0x7ffed323ead4, as expected and so are the outputs for all &A+i

But in the arrf() function, the outputs are not as expected, even &A+0 produces an output different from the base address. More strangely, the addresses are decreasing instead of increasing. Why is that?

19aksh
  • 123
  • 1
  • 7
  • `(&A+i)` is an automatic code smell. It should be considered verification that you need to better understand how pointer arithmetic works, and what the *type* of the expression `&A` really is. In this case, `int (*)[5]` in main. But since `A` is a simple` int*` in the function parameter list, `&A` is `int**` there. Thus the difference. – WhozCraig Aug 09 '21 at 02:41
  • 1
    May I ask why in the name holy name of Dennis Richie you're taking the address of that variable in the first place? Taking the address of a stack array almost never makes a lick of sense. – Roflcopter4 Aug 09 '21 at 02:46
  • In `main`, `A` has type `int [5]`, but in `arrf`, `A` has type `int *`. While adding an integer to `A` will work the same in both functions, adding an integer to `&A` will not, since `&A` has type `int (*)[5]` in `main` and `int **` in `arrf`. Those two types are quite different, and are not compatible. – Tom Karzes Aug 09 '21 at 02:46
  • 1
    Note that if x is a variable (of any type), then `(&x + n)` is undefined behaviour whenever `n > 1`. – n. m. could be an AI Aug 09 '21 at 04:32
  • @AK So if you understood, write an answer and accept that for the sake of others. – U. Windl Aug 09 '21 at 08:31
  • @U.Windl I've already accepted dbush's answer – 19aksh Aug 09 '21 at 13:45

2 Answers2

3

When an array is passed to a function, it is converted to a pointer to its first element. So A in main is an array while A in arrf is a pointer.

This also means that in arrf, that &A has type int **, so pointer arithmetic is done in units of int * whose size is apparently 8 on your system.

Also, A in arrf is a separate variable from A in main, so its address will be different (most likely on the program's stack).

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Thank you. So is ```&A + 0``` is different from ```&A``` in the function ```arrf()``` and from that for each ```i`` it is incremented by 8-bytes as the pointer size is 8 in 32-bit compiler ? – 19aksh Aug 09 '21 at 03:25
1

When you are passing address of a array into a function it has no information(of the number of array elements) that how was the previous pointer incrementation used to work. To overcome that you may need to explicitly tell the compiler that how should the arithmetic of the pointer behave.

I have modified the example for you to make it work.

#include <stdio.h>
void arrf(int (*A)[5],int n)//Here
{
  printf("\n\nInside arrf()");
  printf("\n&A ---> %p",A);
  for(int i=0;i<n;i++)
        printf("\n&A + %d  ---> %p",i,(A+i));
}

int main()
{
  int A[]={1,2,3,4,5};
  int n=5;
  printf("Inside main()");
  printf("\n&A --->%p",A);
  for(int i=0;i<n;i++)
        printf("\n&A + %d  ---> %p",i,(&A+i));
        arrf(&A,n);//Here
        return 0;
}

Also read about : c-pointer-to-array-array-of-pointers-disambiguation

Sreeraj Chundayil
  • 5,548
  • 3
  • 29
  • 68
  • 1
    *"When you are passing address of a array into a function it decays into pointer"* - The address does not decay to a pointer. It already is a pointer. If you pass the array (not the address of the array) it will decay to a pointer. – klutt Aug 09 '21 at 04:06
  • 1
    *"When you are passing address of a array into a function it has no information"* - Not sure what you're trying to say. This is also true if you pass the array directly, but your post gives the impression that it does not. – klutt Aug 09 '21 at 04:20