Referring to the line with the comment:
The example prints "one", then prints garbage.
#include <iostream>
int main() {
const char* a[3] = { "one", "two", "three" };
const char*(*p)[3] = &a;
for(int i = 0; i < 3; i++) {
std::cout << *p[i] << std::endl; // this line
}
return 0;
}
It works after changing to this:
std::cout << (*p)[i] << std::endl;
Darker arrow denotes pointer to an array. On dereferencing a pointer expression we get a value pointed to by that pointer expression. Pointer to an array points to an array, so on dereferencing it, we should get the array, and the name of array denotes the base address.
As we already know that "what is a pointer", a pointer is a variable that stores the address of another variable. The dereference operator is also known as an indirection operator, which is represented by (*). When indirection operator (*) is used with the pointer variable, then it is known as dereferencing a pointer.
array[i] = *(array+i) (expansion of [i] ). Similarily, (*p)[i] = *(*(p+i)) . So, we need to dereference twice to access the value. If you want to access, array[0][0] , you have to use *(*(p+0)+0) = **p; , Similarily, array[0][1] can be accessed using *(*(p+0)+1) = *((*p)+1);
In computer programming, a dereference operator, also known as an indirection operator, operates on a pointer variable. It returns the location value, or l-value in memory pointed to by the variable's value. In the C programming language, the deference operator is denoted with an asterisk (*).
p
is a pointer to an array of 3 elements like this:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ p
Note that it points at the whole array, not a single element of it.
The expression *p[i]
is treated as *(p[i])
due to operator precedence (which is equivalent to *(*(p + i))
). This means that you are indexing the pointer to the array. If you do p[1]
, for example, you move the pointer along to the "next" array and attempt to dereference it:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ p + 1
As we can see, there is nothing there, and you'll get undefined behaviour. However, when you do (*p)[i]
(equivalent to *((*p) + i)
), you are making sure the dereference happens first. The dereference gives us the array itself, which can then be implicitly converted by array-to-pointer conversion to a pointer to the arrays first element. So what you get is:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ *p
In this case, the pointer is pointing at the array element and not the whole array. If you then index, for example, (*p)[1]
, you'll get:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ (*p) + 1
This gives you a valid const char*
which can then be outputted by cout
.
Operator precedence.Without ()
operator []
will be called first and result of it will be dereferenced
. With ()
- firstly will be dereference
and then call to operator []
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With