Lately I started learning pointers and references in c++ (not just the usual use of them,but all kinds of ways,I don\'t want to have problems with them in near future).
An array is an object that contains a contiguous block of N objects where N is some constant size. The address of the array is the start of the array so the address of the first object and the addresss of the array are the same thing.
A pointer to an array is a unique object. Since it is it's own object it has its own address separate from the address that it holds. so with int* t=new int[10];
&t
is the address of t
where &t[0]
is the address of the first element of the array that was allocated by new.
&t
is taking the address of the pointer t
, not the address of the first element. The address of the first element is just t
(as t
is an int*
, which points to the block of memory).
t
is a pointer declared on the stack which holds the address of an array on the heap. &t
gets the address of t
, AKA the location of t
on the stack. If you want to access the first member of the array, you can either do *t
or t[0]
. C++ automatically dereferences and does pointer arithmetic based on the type of t
when you use the bracket notation.
However, &t[0]
essentially gets you the address of t[0]
, which is why it is different from &t
, as &t
lives on the stack while &t[0]
lives on the heap. So if you want the address of t[0]
, you can use that notation, otherwise stick to t[0]
if you just want the values.
Arrays are first-class entities of the language, so when you declare an array variable
int a[10];
the compiler knows the dimensions of the array. When you allocate a dynamic storage space
int* p = new int[10];
Only you and the allocator know how large this space is.
In the array version, a
is the array. It has an address, but that address is held by the compiler during compilation. In the allocation pardigm, p
is the address of the data, which won't be known until run time.
What causes people to be confused is that by and large the two seem interchangeable: you can do pointer and array math with both, use either where a pointer is expected:
void f(int*);
int a1 = a[1];
f(a);
int p1 = p[1];
f(p);
This is by design, it's something called array-pointer-equivalence, emphasis mine:
Much of the confusion surrounding arrays and pointers in C can be traced to a misunderstanding of this statement. Saying that arrays and pointers are ''equivalent'' means neither that they are identical nor even interchangeable. What it means is that array and pointer arithmetic is defined such that a pointer can be conveniently used to access an array or to simulate an array. In other words, as Wayne Throop has put it, it's ''pointer arithmetic and array indexing [that] are equivalent in C, pointers and arrays are different.'')
Specifically, the cornerstone of the equivalence is this key definition:
A reference to an object of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T.