Reputation: 97
I've been studying C++ for couple of months now and just recently decided to look more deeply into the logic of pointers and arrays. What I've been taught in uni is pretty basic - pointers contain the address of a variable. When an array is created, basically a pointer to its first element is created.
So I started experimenting a bit. (and got to a conclusion which I need confirmation for). First of all I created
int arr[10];
int* ptr = &arr[5];
And as you would imagine
cout << ptr[3];
gave me the 8th element of the array. Next I tried
int num = 6;
int* ptr2 = #
cout << ptr2[5];
cout << ptr2 + 5;
which to my great delight (not irony) returned the same addresses. Even though num wasn't an array.
The conclusion to which I got: array is not something special in C++. It's just a pointer to the first element (already typed that). More important: Can I think about every pointer in the manner of object of a class variable*
. Is the operator []
just overloaded in the class int*
? For example to be something along the lines of:
int operator[] (int index){
return *(arrayFirstaddress + index);
}
What was interesting to me in these experiments is that operator []
works for EVERY pointer. (So it's exactly like overloading an operator for all instances of the said class)
Of course, I can be as wrong as possible. I couldn't find much information in the web, since I didn't know how to word my question so I decided to ask here. It would be extremely helpful if you explained to me if I'm right/wrong/very wrong and why.
Upvotes: 2
Views: 164
Reputation: 35154
You find the definition of subscripting, i.e. an expression like ptr2[5]
in the c++ standard, e.g. like in this online c++ draft standard:
5.2.1 Subscripting [expr.sub]
(1) ... The expression E1[E2] is identical (by definition) to *((E1)+(E2))
So your "discovery" sounds correct, although your examples seem to have some bugs (e.g. ptr2[5]
should not return an address but an int value, whereas ptr2+5
is an address an not an int value; I suppose you meant &ptr2[5]
).
Further, your code is not a prove of this discovery as it is based on undefined behaviour. It may yield something that supports your "discovery", but your discovery could still be not valid, and it could also do the opposite (really!).
The reason why it is undefined behaviour is that even pointer arithmetics like ptr2+5
is undefined behaviour if the result is out of the range of the allocated memory block ptr2
points to (which is definitely the case in your example):
5.7 Additive operators
(6) ... Unless both pointers point to elements of the same array object, or one past the last element of the array object, the behavior is undefined.
Different compilers, different optimization settings, and even slight modifications anywhere in your program may let the compiler do other things here.
Upvotes: 3
Reputation: 36597
An array in C++ is a collection of objects. A pointer is a variable that can store the address of something. The two are not the same thing.
Unfortunately, your sample
int num = 6; int* ptr2 = # cout << ptr2[5]; cout << ptr2 + 5;
exhibits undefined behaviour, both in the evaluation of ptr2[5]
and ptr2 + 5
. Pointer expressions are special - arithmetic involving pointers only has defined behaviour if the pointer being acted on (ptr2
in this case) and the result (ptr2 + 5
) are within the same object. Or one past the end (although dereferencing a "one past the end" pointer - trying to access the value it points at - also gives undefined behaviour).
Semantically, *(ptr + n)
and ptr[n]
are equivalent (i.e. they have the same meaning) if ptr
is a pointer and n
is an integral value. So if evaluating ptr + n
gives undefined behaviour, so does evaluating ptr[n]
. Similarly, &ptr[n]
and ptr + n
are equivalent.
In expressions, depending on context, the name of an array is converted to a pointer, and that pointer is equal to the address of that array's first element. So, given
int x[5];
int *p;
// the following all have the same effect
p = x + 2;
p = &x[0] + 2;
p = &x[2];
That does not mean an array is a pointer though.
Upvotes: 2