In C, I know I can dynamically allocate a two-dimensional array on the heap using the following code:
int** someNumbers = malloc(arrayRows*sizeof(int*));
fo
Suppose, we have a1
and a2
defined and initialized like below (c99):
int a1[2][2] = {{142,143}, {144,145}};
int **a2 = (int* []){ (int []){242,243}, (int []){244,245} };
a1
is a homogeneous 2D array with plain continuous layout in memory and expression (int*)a1
is evaluated to a pointer to its first element:
a1 --> 142 143 144 145
a2
is initialized from a heterogeneous 2D array and is a pointer to a value of type int*
, i.e. dereference expression *a2
evaluates into a value of type int*
, memory layout does not have to be continuous:
a2 --> p1 p2
...
p1 --> 242 243
...
p2 --> 244 245
Despite totally different memory layout and access semantics, C-language grammar for array-access expressions looks exactly the same for both homogeneous and heterogeneous 2D array:
a1[1][0]
will fetch value 144
out of a1
arraya2[1][0]
will fetch value 244
out of a2
arrayCompiler knows that the access-expression for a1
operates on type int[2][2]
, when the access-expression for a2
operates on type int**
. The generated assembly code will follow the homogeneous or heterogeneous access semantics.
The code usually crashes at run-time when array of type int[N][M]
is type-casted and then accessed as type int**
, for example:
((int**)a1)[1][0] //crash on dereference of a value of type 'int'