I've read this example for allocating an array of pointers, and allocating a contiguous block of memory as an alternative to a two dimensional array, allowing specifying both dimensions at run time: http://c-faq.com/aryptr/dynmuldimary.html
int **array2 = malloc(nrows * sizeof(int *));
array2[0] = malloc(nrows * ncolumns * sizeof(int));
for(i = 1; i < nrows; i++)
array2[i] = array2[0] + i * ncolumns;
With this approach you can also reference values with two sets of brackets as:
array2[i][j]
In contrast, a single malloc() call could force you to compute an index value, and reference the array using on one set of brackets, like this:
array2[i*ncolumns + j]
However, in order to properly free memory with the approach using two sets of brackets, you must do:
free(array2[0]);
free(array2);
Is it possible to do the approach of using two sets of brackets, have entirely contiguous memory, but do it all with only 1 malloc() call? (which goes hand in hand with contiguous memory).
And if so, then you would ideally be able to free memory with a single call:
free(array2);
With the approach of calling malloc() twice, memory is not necessarily entirely contiguous. The buffer where all the data is ultimately stored is contiguous, but the array of pointers for retrieving each row can be located elsewhere in memory (since it is a separate malloc() call).
Can the entire allocated buffer start off at the address contained in array2, and then the data stored starting at the address in array2[0] begin offset from that by nrows * sizeof(int *)?
The C FAQ also lists an example:
int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));
However, this fixes one dimension at compile time. Is it possible for a single malloc() call, access using two sets of brackets, and specify both dimensions at run time?
Why will this fail, or what is wrong with this?
int i;
size_t sizeof_rows = nrows * sizeof(int *);
size_t total = sizeof_rows + nrows * ncolumns * sizeof(int);
int **array2 = malloc(total);
array2[0] = (int *)(array2 + sizeof_rows);
for (i = 1; i < nrows; i++)
array2[i] = array2[0] + i * ncolumns;