Hi,
I can't understand why this code causes a "memory read exception" at
int x=**a;
Because you lied to the compiler. Arrays are not pointers and
pointers are not arrays.
void pass(int** a)
{
int x=**a;
a is a pointer to pointer to int. To do determine the value of the
int itself, the following steps are required:
1 - Determine the value of a. It was passed "by value" to the
function using whatever calling convention is appropriate for your
system so this pretty straight forward.
2 - Use this value as the address of a pointer to int.
3 - Determine the value of this pointer.
4 - Use this value as the address of the int.
5 - Determine the value of the int.
6 - Store this value in x. (Not part of determining the value
but the concluding step in the initialization.)
int main(void) please.
{
int arr[2][2]={{1,2},{3,4}};
pass(arr);
Since this statement has a syntax error and will not compile cleanly,
why did you bother to execute the code at all. If you did not see the
mandatory diagnostic, you need to up the warning level on your
compiler.
You pass a 2D array to the function. In this context, the array name
evaluates to the address of the first element with type pointer to
first element. In other words, this is identical to coding
pass(&arr[0]);
arr[0] is itself an array of 2 int. A pointer to arr[0] has type
pointer to array of 2 int, written as int (*)[2].
The syntax error is because an int(*)[2] is incompatible with an
int**. There is no implicit conversion between the two.
Apparently on your system the two pointer types have similar
representations (not uncommon). pass will take the value and treat it
as the address of a pointer to int (steps 1 and 2 above).
Undefined behavior #1. Since the address is actually the
address of arr[0] which is an array of 2 int, it is really the address
of arr[0][0], a normal int. You have no idea if the alignment of this
int is suitable for a pointer to int.
Undefined behavior #2. pass will attempt to use the value at
this location as the address of an int (steps 3 and 4 above). You
have no idea if the value of the int that is actually at that location
is a valid address. It could be an invalid address or even a trap
representation.
Undefined behavior #3. pass will attempt to extract the int
value at this "address" (step 5 above). Since the value at this new
address was an int and not an address to begin with, attempting to
dereference it should be an obvious no-no. This is probably where
your system decided enough was enough.
}
The assignment of int int x=**a in the main function works.
There is no a in main. Perhaps you meant
int x = **arr;
This would work because the compiler know arr is a 2D array. *arr is
identical to arr[0] which is a1D array. **arr is identical to *arr[0]
which is identical to arr[0][0] which is the first int in the 1D array
and a perfectly valid value to assign to the int x.
Tanks for your help,
Markus
Remove del for email