-2

I often hear that the name of an array is constant pointer to a block of memory therefore statement like

int a[10];

and

int * const p= a;

must be equal in a sense that p is pointer that points to the same block of memory as array a[] and also it may not be changed to point to another location in memory.

However if you try to print sizeof these two pointers you get different results:

cout<< sizeof(a); // outputs size of 10 integer elements

While

cout<< sizeof(p); // outputs sizeof pointer to int

So, why do compilers treat these two differently? What's the true relation between arrays and pointers from compiler point of view?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Arash
  • 141
  • 10
  • 8
    You've often been mislead - or you've simply misunderstood. Arrays are not pointers. – eerorika Oct 26 '16 at 20:51
  • An array of type `T` and size `N` is `N`-many `T`-type objects placed in sequential memory. Just because you can make a pointer point to that memory, doesn't make an array be a pointer. – DeiDei Oct 26 '16 at 20:54
  • They are different because c++ is a strongly typed language, and sizeof in particular refers to the type. There are plenty of runtime cases where a and p can be used interchangably (as long as you stay within the correct range), but they still are different type. – Kenny Ostrom Oct 26 '16 at 21:25

1 Answers1

6

I often hear that the name of an array is constant pointer to a block of memory

You've often been mislead - or you've simply misunderstood. An array is not a constant pointer to a block of memory. Array is an object that contains a sequence of sub-objects. All objects are a block of memory. A pointer is an object that contains an address of an object i.e. it points to the object.

So in the following quote, a is an array, p points to the first sub-object within a.

int a[10];

and

int * const p= a;

must be equal in a sense that p is pointer that points to the same block of memory as array a[] and also it may not be changed to point to another location in memory.

If that is your definition of equal, then that holds for non-array objects as well:

char c;
int * const p = &c;

Here p "points to the same memory as c" and may not be changed to point to another location in memory. Does that mean that char objects are "equal" to pointers? No. And arrays aren't either.

But isn't a (the name of the array), a constant pointer that points to the same element of the array?

No, the name of the array isn't a constant pointer. Just like name of the char isn't a constant pointer.

the name of an array holds the address of the first element in the array, right?

Let's be more general, this is not specific to arrays. The name of a variable "holds the address" of the object that the variable names. The address is not "held" in the memory at run time. It's "held" by the compiler at compile time. When you operate on a variable, the compiler makes sure that operations are done to the object at the correct address.

The address of the array is always the same address as where the first element (sub-object) of the array is. Therefore, the name indeed does - at least conceptually - hold the same address.

And if i use *(a+1), this is the same as a[1], right? [typo fixed]

Right. I'll elaborate: One is just another way of writing another in the case of pointers. Oh, but a isn't a pointer! Here is the catch: The array operand is implicitly converted to a pointer to first element. This implicit conversion is called decaying. This is special feature of array types - and it is the special feature which probably makes understanding the difference between pointers and arrays difficult the most.

So, even though the name of the array isn't a pointer, it can decay into a pointer. The name doesn't always decay into a pointer, just in certain contexts. It decays when you use operator[], and it decays when you use operator+. It decays when you pass the array to a function that accepts a pointer to the type of the sub-object. It doesn't decay when you use sizeof and it doesn't decay when you pass it to a function that accepts an array by reference.

Community
  • 1
  • 1
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • But isn't a (the name of the array), a constant pointer that points to the same element of the array? – Arash Oct 26 '16 at 21:05
  • @Arash No. See the edit. – eerorika Oct 26 '16 at 21:07
  • @Arash The name of an array is *implicitely converted* to a constant pointer you're thinking about. But it's not a pointer by itself. – HolyBlackCat Oct 26 '16 at 21:25
  • Thank you for your comments. But i still have hard time understanding something. Ok, an array is not a pointer. But the name of an array holds the address of the first element in the array, right? And if i use *(a+1), this is the same as a[2], right? so to me it seems that array somewhat behaves like a pointer. Also in my example I can use p[2] to access value stored in a[2]. So the pointer and the array are related somehow , right? What am i missing here? – Arash Oct 26 '16 at 21:27
  • @Arash The name of an array is converted to a pointer when it's used as a pointer. – HolyBlackCat Oct 26 '16 at 21:31
  • Thank you all! It finally clicked! – Arash Oct 26 '16 at 21:33
  • @Arash `*(a+1)` is `a[1]`, not `a[2]` (Probably a typo, but people sometimes get mixed up by the zero-based indexing) – M.M Oct 26 '16 at 21:35
  • @user2079303 your example with `char c;` is actually a good illustration of the principle that a non-array object can be accessed as if it were an array of 1 object (using different syntax) – M.M Oct 26 '16 at 21:36
  • @Arash I've further elaborated the differences and similarities. – eerorika Oct 26 '16 at 21:53