2

I have some code (below) where I am assigning the address of an integer array to a pointer. I am assigning in two ways and expect two different outputs but in both cases the output is the same.

main()
{
   int a[]={11,2,3};
   int *p=&a;
   printf("%d",*(p+1));
}

It should give me some garbage value since p is pointing to next 1D array

main()
{
   int a[]={11,2,3};
   int *p=a;
   printf("%d",*(p+1));
}

This should print 2.

However BOTH of these functions print 2.

This is not what I expected. Can anyone explain what's happening?

Can anybody tell how i make pointer pointing to whole array than to just individual element.

Amit Singh Tomar
  • 8,380
  • 27
  • 120
  • 199
  • possible duplicate of [C: How come an array's address is equal to its value?](http://stackoverflow.com/questions/2528318/c-how-come-an-arrays-address-is-equal-to-its-value) – phimuemue Sep 02 '11 at 08:14
  • @phimuemue i don't find it exact duplicate of what you have suggested!! – Amit Singh Tomar Sep 02 '11 at 08:18
  • I thought you were talking about the first two outputted lines in my proposed duplicate question. – phimuemue Sep 02 '11 at 08:23

3 Answers3

3

This is because a bare array identifier decays to a pointer of type int * in this case.

&a evaluates to a pointer to the whole array (of type int (*)[3]) which, although of a different type, is the same address as the address of the first element.

Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
3

If you compile the first program you will get a compiler warning:

 warning: initialization from incompatible pointer type

Because the type of p is pointer to integer but the type of &a is pointer to array of integer. Compiling the second program is fine, because againphas typeint*andahas typeint[]` (i.e., array of integer) but in C, you can pass/assign an integer array to an integer pointer just fine. The value of the pointer is assigned the starting address of the array.

When you define an array with square brackets in C, the array is placed immediately in the stack or data section, so the starting address of the array is the same as the address of the array variable itself! This is different from arrays created with malloc.

What this means for you is this: Suppose the variable a is allocated at address 4e78ccba. This means that &a is 4e78ccba. But in C, the value of a when passed/assigned to a pointer is by definition the address of the beginning of the array, so this is also 4e78ccba.

Again, if you set things up with malloc things will be different. (Try it!!) And by the way, pay attention to the warnings. :) This is an interesting question because C is so weakly typed it only gave you a warning in the first case. A stronly typed language would not have liked the mixing of an integer pointer with an integer array pointer.

ADDENDUM

Here is some code that shows how you can actually differentiate the pointer to the first element and the pointer to the whole array:

#include <stdio.h>
int main() {
    /* a is an array of ints, but can be used as a pointer to int */
    int a[] = {11, 2, 3};

    /* Using a as an int pointer */
    int* p = a;
    printf("%d\n", *(p+1));

    /* Now here is how to make a pointer to the array itself! */
    int (*q)[] = &a;
    printf("%d\n", (*q)[2]);

    return 0;
}

This program outputs

2
3
Ray Toal
  • 86,166
  • 18
  • 182
  • 232
  • Thanks @Ray this simplifies a lost of things!!but i one thing i would like to know how it do i define a pointer that point to whole array – Amit Singh Tomar Sep 02 '11 at 08:57
  • @Amit, sure no problem. I will add an explanation in one sec. – Ray Toal Sep 02 '11 at 09:13
  • It would appear so, as you are typing `p` as a pointer to an array of 5 elements. – Ray Toal Sep 02 '11 at 09:41
  • I don't follow what you're saying about arrays created with `malloc` being different, and I suspect it contains mistaken reasoning. Could you clarify? – R.. GitHub STOP HELPING ICE Sep 02 '11 at 12:46
  • @R.. If you declare `int a[5]` for example, then `a` and `&a` will both "be the same address" (on the stack or in the global data section) but if you declare `int* a = malloc(5*sizeof(int))` then `a` will "be" the address of the help of the allocated array, but `&a` will be the address of the pointer variable itself on the stack or in the data section. In both cases `a == &a[0]` of course. So I was just saying that the "equivalence" of `a` and `&a` holds for real arrays allocated in place but does not hold when `a` is declared as a pointer and the actual array is malloced. – Ray Toal Sep 02 '11 at 13:48
  • This has nothing to do with `malloc`. It merely pertains to the fact that pointers and arrays are not the same thing, and your `int *a;` is a pointer, not an array. It merely *points to* the first element of an array, but this would also be the case if you did `int b[5], *a=b;` – R.. GitHub STOP HELPING ICE Sep 02 '11 at 14:15
  • True, true, it was probably useless to bring it up. But it sounded like a useful thing to point out though, since the OP's question expressed, it seemed, an expectatation that `a` and `&a` would be different. That is how I read the question. It seemed useful to say, "yeah well they _would_ be different for arrays on the heap, but in this case the array is real and inlined, so they are the same." – Ray Toal Sep 02 '11 at 15:03
1

Both times it is a pointer to an int, and the p+1 only advances by the size of an int no matter where the pointer actually came from.

Hannesh
  • 7,256
  • 7
  • 46
  • 80
  • 1
    I guess in first case its pointer to whole array rather than other way around!! – Amit Singh Tomar Sep 02 '11 at 08:19
  • 1
    Fair enough! But since you write int *p, C only knows that it's a pointer to an int. When you write int *p = a, the pointer points to the start of the array. – Hannesh Sep 02 '11 at 08:29