7.13 how can I dynamically allocate multi-dimensional arrays?
The traditional solution is to assign a pointer array and initialize each pointer As a dynamically allocated ''column ". The following is a two-dimensional example:
#include <stdlib.h>int **array1 = malloc(nrows * sizeof(int *));for(i = 0; i < nrows; i++) array1[i] = malloc(ncolumns * sizeof(int));
Of course, in real code, all malloc return values must be checked. You can also use sizeof (* array1) and sizeof (** array1) instead of sizeof (int *) and sizeof (INT ).
You can make the content of the array continuous, but it will be difficult to re-allocate columns later. You have to use a pointer arithmetic:
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;
In either case, dynamic Array members can be accessed using the normal array subscript arrayx [I] [J] (for 0 <= I <nrows and 0 <= j <ncolumns ).
If the preceding two schemes are unacceptable for some reason indirectly, you can simulate two-dimensional arrays by using the same dynamically allocated one-dimensional array:
int *array3 = malloc(nrows * ncolumns * sizeof(int));
However, you must manually calculate the subscript and use array3 [I * ncolumns + J] to access the I and j members. You can use a macro to hide the displayed computation, but use parentheses and commas to call it. This does not look like the multi-dimensional array syntax, and the macro needs to access at least one dimension.
Another option is to use an array pointer:
int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));
However, this syntax becomes terrible and the runtime can only determine one dimension at most.
Of course, when using these technologies, you must remember to release arrays when you don't need them. In addition, you may not mix dynamic arrays and traditional static allocation arrays.
Finally, you can use a variable-length array in c99.
All of these technologies can extend to three dimensions or more dimensions.
In addition:
Rules that convert arrays into pointers cannot be recursively applied. Arrays (two-dimensional arrays in C) are converted into arrays instead of pointers. Array pointers are often confusing and need to be careful.
If you pass two arrays to the function:
int array[NROWS][NCOLUMNS]; f(array);
Then the function declaration must match:
void f(int a[][NCOLUMNS]) { ... }
Or
Void F (INT (* AP) [ncolumns])/* AP is an array pointer */{...}
In the first declaration, the compiler performs an implicit conversion from the ''array array "to the ''array Pointer". The pointer definition in the second form is obvious. Because the called function does not allocate addresses to arrays, it does not need to know the total size, so the number of rows nrows can be omitted. But the array width is still important, so the Column Dimension ncolumns (for three-dimensional or multidimensional arrays, related dimensions) must be retained.
If a function has been defined as a pointer that accepts pointers, it is almost certainly meaningless to directly input a two-dimensional array to it.