Arash Arash - 1 month ago 9
C++ Question

Array and pointers in c++

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?

Answer

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.

So, even though the name of the array isn't a pointer, it can decay into a pointer. It decays when you use operator[], and it decays when you use a+1 and it decays when you use +a. It doesn't decay when you use sizeof a.

Comments