like this : int (*arr)[M] = malloc(sizeof(int[N][M]));
arr is pointer to int[M].
use like arr[0][M-1];
and free(arr);
like this : int (*arr)[M] = malloc(sizeof(int[N][M]));
arr is pointer to int[M].
use like arr[0][M-1];
and free(arr);
int ** arr = malloc(N*sizeof(int[M]));
is incorrect C code, if you simulate it by allocating once
int *arr = malloc(N*M*sizeof(int));
and access it by
arr[i*M + j],
this is an analog to arr[I][j] in your first case.
Videos
There are 3 ways that I know of to dynamically allocate a multidimensional array in C:
1- The malloc -> malloc -> malloc... way
int x = 4, y = 5;
int** arr = malloc(sizeof(*arr) * x);
for (int i = 0; i < x; ++i) {
arr[i] = malloc(sizeof(arr[0]) * y);
}This seems to be the worst method of them all. It's verbose to create and free and generates fragmented memory blocks. Also gets progressively bigger the more dimensions there are.
2- The 1D array with indexing way
int index(int x, int y, int maxX)
{
return y * maxX + x;
}
int main(void)
{
int x = 4, y = 5;
int* arr = malloc(sizeof(*arr) * x * y);
// get element at position (0, 2)
int elem = arr[index(0, 2, x)];
}
This is better but not much. Having to call index every time you access the array is a pain. You would also need to create a index function for each number of dimensions.
2.1- The indexing way with a macro
#define ARR(X, Y) arr[Y * x + X]
int main(void)
{
int x = 4, y = 5;
int* arr = malloc(sizeof(*arr) * x * y);
// get element at position (0, 2)
int elem = ARR(0, 2);
}I guess you could consider this better, but I personally don't really like it. Also has the same problems that number 2 has.
3- The VLA way
int x = 4, y = 5, z = 10, w = 2; int (*arr2D)[y] = malloc(sizeof(int[x][y])); int (*arr3D)[y][z] = malloc(sizeof(int[x][y][z])); int (*arr4D)[y][z][w] = malloc(sizeof(int[x][y][z][w]));
This really looks like the perfect solution. Easy to adapt to any number of dimensions and easy to index. The only downside I could find is that VLA support is not required since C11, but I'm not sure if any big compiler doesn't support them.
So, is number 3 really the best way of doing it by a far margin? Or are there any downsides to it that I don't know of? What is the method you would use on some real world project?
You say in the comments that n is the number of rows. So you need to allocate n rows each of length m. Therefore, the second for loop condition should be i < n. Also, you should check the return value of malloc for NULL in case it fails to allocate memory. I suggest the following change -
long long **a = malloc(n * sizeof(*a));
for (i = 0; i < n; i++) {
a[i] = malloc(m * sizeof(*a[i]));
}
Please note that a multi-dimensional array is not a fundamentally new type. It's simply an array of elements where each element itself is an array (for a 2D array), an array of arrays (for a 3D) array and so on. If you are using C99, you can allocate your array cleanly and succinctly as
int nrow = 4; // number of rows
int ncol = 8; // number of columns
// define arr to be a pointer to an array of ncol ints, i.e.,
// arr is a pointer to an object of type (int[ncol])
int (*arr)[ncol] = malloc(sizeof(int[nrow][ncol]));
// check the result of malloc for NULL
if (arr == NULL) {
printf("malloc failed to allocate memory\n");
// handle it
}
// do stuff with arr
for (int i = 0; i < nrow; i++) {
for (int j = 0; j < ncol; j++) {
arr[i][j] = i + j;
}
}
// after you are done with arr
free(arr);
You should also go through this - How do I work with dynamic multi-dimensional arrays in C?
You have three errors: The first is that you allocate only 5 secondary arrays, but in the input you loop over 6 of them.
The second problem is that array indices are zero-based, i.e. the index start at zero and goes to the size minus one.
The third problem is that you scan for two numbers (why?), but you provide only one destination pointer to scanf.