1

Okay, consider following piece of code in C:

int main(int argc, char *argv[])
{
     int arr[10];
     arr;     // This has an address to the first element of arr[10] and is of type int *
     &arr;    // Has same value as arr but the type is a pointer to an array of [10] ints. Also pointer arithmetic here would be different as compared to arr.
     int var; //var is a variable and has an address. &&var --> Doing this would be invalid. If so, then what is arr? Why is &arr allowed? 
     return 0;
}

I know the difference between above two expressions but what I am having a hard time understanding is why these two have the same value? So I have following two questions regarding this:

  1. Considering if arr[0] has an arbitrary location of 0x100, then why arr and &arr has the same value? How exactly does compiler treat these two expressions and how would they be really implemented in memory?
  2. What exactly is the use of having &arr in C? Since, arr is already an address, why is & operator even allowed on it?

EDIT 1: Removed reference to ptr & ptr2Array as people were misinterpreting the question.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
Cheshar
  • 571
  • 1
  • 7
  • 21
  • 1
    Suppose you have `struct X { int a; } x;` Are you equally claiming that there's no use for `&x` since you might as well use `&x.a`? – Kerrek SB Jun 18 '15 at 19:41
  • 1
    possible duplicate of [How come an array's address is equal to its value in C?](http://stackoverflow.com/questions/2528318/how-come-an-arrays-address-is-equal-to-its-value-in-c) – missimer Jun 18 '15 at 19:44
  • `ptr` and `&arr` have the same value, but different types. – Eugene Sh. Jun 18 '15 at 19:45
  • 2
    The *expression* `arr` evaluates to an address (a pointer) in most contexts. That is subtly but importantly different from array `arr` *being* a pointer. Arrays are *not* pointers. – John Bollinger Jun 18 '15 at 19:48
  • https://ideone.com/E60t96 – Eugene Sh. Jun 18 '15 at 19:49
  • 1
    Moreover, `ptr` and `ptr2Array` may receive numerically equal values in your code, but they are semantically different. For one thing, `ptr + 1 != ptr2Array + 1` . – John Bollinger Jun 18 '15 at 19:50
  • @All: I know pointers and arrays are not similar. I also know that arrays tend to decay into pointers in expressions with 3 exception. My question here is how array is really being treated by compiler and addressed in memory? What exactly is "arr" and how is it treated? If arr is already an address than why &arr is the same address? Also, I will remove 'ptr' & 'ptr2Array' as it is confusing a lot of people. – Cheshar Jun 18 '15 at 19:54
  • So what is the question? Different types are giving different context for some operations, resulting in different outcomes, even if having the same value. It is not confusing you when signed and unsigned types can have the same values, right? – Eugene Sh. Jun 18 '15 at 20:03
  • `arr` *isn't* an address, any more than any other variable such as `var` is an address. – Mark Ransom Jun 18 '15 at 20:40

4 Answers4

1

The main difference between ptr and &arr is that they are two different pointer types.

Consider this:

*ptr = 10; // Valid
*ptr2Array = 10; // Not valid.

You need to use:

(*ptr2Array)[0] = 10; 

And

ptr + 1 = (void*)ptr + sizeof(int)
ptr2Array + 1 = (void*)ptr2Array + sizeof(arr)

The numerical offset between ptr and ptr+1 is sizeof(int).
The numerical offset between ptr2Array and ptr2Array+1 is sizeof(int)*10.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

Considering if arr[0] has an arbitrary location of 0x100, then why arr and &arr has the same value? How exactly does compiler treat these two expressions and how would they be really implemented in memory?

Because an array is a memory address. A pointer is an object that stores the address of another object. An array is a memory address, and in most cases it decays into a pointer to the first element. Taking its address with the & operator happens to be outside of these common cases.

There are 3 conditions under which an array name does not decay into a pointer to its first element:

  1. It is the operand of sizeof
  2. Its address is taken with the & operator
  3. It is a character string literal

So yes, array and &array have the same address, but as you said, they have a different type.

What exactly is the use of having &arr in C? Since, arr is already an address, why is '&' operator even allowed on it?

It's a pointer type like any other. What if you want to build an array of pointers to arrays? Its usage is pretty much the same as for any other pointer type.

Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70
0

1:

Look at people waiting in line for something.
Note how the person who's first in line stands exactly where the line starts.
The same thing applies to where the array starts and where its first element is located.

As an example, here's a sketch of an array of four zero chars laid out in memory:

Address:   0x10 0x11 0x12 0x13
Elements: | 0  | 0  | 0  | 0  |

The address of the array, 0x10, is the same as the address of its first element.

2:

arr is not an address, it's a variable whose value is an address.
&arr is the address of the variable, not of its value.
This is exactly the same as if you have int x = 23;, &x is not the address of the number 23, but of the variable x.
&&x is illegal because you can't take the address of a value (e.g. &(1 + 1) is equally illegal).

Taking the address of an array can be used e.g. for bounds-safe parameter passing:

/* This function only takes pointers to 10-element arrays. */ 
void foo(int (*x)[10]);

int a[10];
foo(&a); /* OK */
int c[3][10];
foo(&c[1]); /* OK */
int b[11];
foo(&b); /* Doesn't compile */
foo(a); /* Also doesn't compile */

(More formally, this discussion would refer to "rvalue" and "lvalue" instead of "value" and "variable", but I think that doesn't clarify anything outside of language-lawyering.)

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
-1

I am having a hard time understanding is why these two have the same value?

Let's lower the abstraction level. What does &arr really mean? When compiled to assembly arr is just a symbol i.e. a labelled memory address, so you are asking for the memory address of a symbol which is well, itself.

(gdb) x arr
0x7fffffffe970: 0x00400410
(gdb) x &arr
0x7fffffffe970: 0x00400410
uname01
  • 1,221
  • 9
  • 9