I've been coding for quite a while, but just realized that my interperation of a very elementary operation may be confused.
int array[10][10];
array[1][1] = 0;
This is sample enough - address of array + (10 * 1 + 1) * sizeof(int) is assigned 0.
But what about when doing dynamic arrays?
int **array;
// malloc/new the base array of pointers - say 10 as above.
array = malloc(10 * sizeof(int *));
// through pointers and alloc each with ints - again 10 per row as above.
for(int i=0; i<10; i++)
array[i] = malloc(10 * sizeof(int);
array[1][1] = 0;
In this example, the compiler has to reference an array on the first layer of the array to get to the second pointer to get to memory. Again, this process is straight forward.
My question here is: How does the compiler know that memory is contiguous and therefore it can just do simple math instead of a reference in the first example, but not the second?
If the answer is: because the compiler knows the size of the array beforehand, so be it, but is there a way to tell the compiler that the dynamic array is a single allocation and therefore it can do the simpler math instead of the extra deref and extra memory fragmenting allocations? Or does this require VLA support to get right as per this post which goes like:
double (*A)[n] = malloc(sizeof(double[n][n]));
Another website listed this as a possibility as well:
int r=3, c=4;
int **arr;
arr = (int **)malloc(sizeof(int *) * r);
arr[0] = (int *)malloc(sizeof(int) * c * r);
Which really got me wondering about how the compiler is figuring things out, or if this is just another way of using VLA support.
For C++, there is boost and nested vectors, but they are even heavier than the above so again, I would avoid those if possible.
Update
Honestly, what I should do here is just compile my above examples and take a gander at the assembler output. That would answer all my questions in no time at all. My misconception was that I assumed that all n-dim array access was done just by doing math similiar to how it is done with compile time known arrays. I did not realize that [][] was doing double duty as **array
with appropriate indexing between each dereference for dynamic allocs, while doing [i*dim+j] for compile time known types. Dynamic 2+ Dimension arrays is just not something I ever have had to do.