The existing answers, though correct, don't make it very clear that there is a fundamental reason (apart from the language rules) why you cannot cast char [10][10]
to char **
. Even if you force the cast by saying something like
char arr[2][2];
char ** ptr = (char **)arr;
it won't actually work.
The reason is that in C and C++ a two-dimensional array is laid out in memory as an array of arrays. That is, in C a two-dimensional array is laid out in memory as a single allocation,
arr -> arr[0][0]
arr[0][1]
arr[1][0]
arr[1][1]
You'll notice that arr
doesn't point to a char *
but to arr[0][0]
which is a char
; therefore, while arr
can be cast to a char *
, it cannot be cast to a char **
.
The correct forced cast would be
char arr[2][2];
char * ptr = (char *)arr;
If you don't want to force the cast (always a good idea if possible!) you would say
char arr[2][2];
char * ptr = arr[0];
or, to make the outcome clearer,
char arr[2][2];
char * ptr = &arr[0][0];
And you now have (in effect) a pointer to an array of 4 characters. [Proviso: I can't find anything in the C standard that prohibits an implementation from adding padding between two rows of an array, but I don't believe that any real-world implementations do so, and common coding practice depends on the assumption that there will be no such padding.]
If you really needed to convert arr
to a char **
you would have to explicitly create an array of pointers:
char arr[2][2]
char * arr_ptrs[2];
char ** ptr;
arr_ptrs[0] = arr[0];
arr_ptrs[1] = arr[1];
ptr = arr_ptrs;
The C language could in principle do this for you automatically if you tried to cast a two-dimensional array to a pointer-to-pointer but that would violate the programmer's expectation that a cast does not have side-effects such as allocating memory.
In Java, by way of comparison, a two-dimensional array is always an array of pointers to arrays, so that the array
char arr[][] = { {'a', 'b'}, {'c', 'd'} };
is laid out in memory as three separate allocations, in arbitrary order and not necessarily adjacent,
arr -> arr[0]
arr[1]
arr[0] -> arr[0][0]
arr[0][1]
arr[1] -> arr[1][0]
arr[1][1]
You will immediately notice that this requires more memory than the equivalent C array, and is slower to evaluate at runtime. On the other hand, it does allow the rows of an array to have different lengths.