I want to dynamically allocate 1 dimension of a 2D array (the other dimension is given). Does this work:
int NCOLS = 20;
// nrows = user input...
double *a
Not quite -- what you've declared is an array of pointers. You want a pointer to an array, which would be declared like this:
double (*arr)[NCOLS];
Then, you'd allocate it like so:
arr = malloc(nrows * sizeof(double[NCOLS]));
It can then be treated as a normal nrows
by NCOLS
2D array. To free it, just pass it to free
like any other pointer.
In C, there's no need to cast the return value of malloc
, since there's an implicit cast from void*
to any pointer type (this is not true in C++). In fact, doing so can mask errors, such as failing to #include <stdlib.h>
, due to the existence of implicit declarations, so it's discouraged.
The data type double[20]
is "array 20 of double
, and the type double (*)[20]
is "pointer to array 20 of double
". The cdecl(1)
program is very helpful in being able to decipher complex C declarations (example).
You have to allocate a new array for each element (each element is a pointer to an array) on the first dimension. You can use a loop for that:
for(i = 0; i < NCOLS; i++)
arr[i] = (double *)malloc(sizeof(double)*nrows);
Do the same to free.
An example:
#include <stdio.h>
#include <stdlib.h>
#define COLS 2
void func(int (**arr)[COLS], int rows)
{
int i, j;
*arr = malloc(sizeof(int[COLS]) * rows);
printf("Insert number: \n");
for(i = 0; i < rows; i++)
for(j = 0; j < COLS; j++)
scanf("%d", &(*arr)[i][j]);
for(i = 0; i < rows; i++)
for(j = 0; j < COLS; j++)
printf("%d\n", (*arr)[i][j]);
}
int main(void)
{
int (*arr)[COLS];
func(&arr, 2);
free(arr);
return 0;
}