Allocate memory 2d array in function C
How to allocate dynamic memory for 2d array in function ? I tried this way:
int main()
{
int m=4,n=3;
int** arr;
allocate_mem(&arr,n,m);
}
void allocate_mem(int*** arr,int n, int m)
{
*arr=(int**)malloc(n*sizeof(int*));
for(int i=0;i<n;i++)
*arr[i]=(int*)malloc(m*sizeof(int));
}
But it doesn't work.
Your code is wrong at *arr[i]=(int*)malloc(m*sizeof(int));
because the precedence of the []
operator is higher than the *
deference operator: In the expression *arr[i]
, first arr[i]
is evaluated then *
is applied. What you need is the reverse (dereference arr
, then apply []
).
Use parentheses like this: (*arr)[i]
to override operator precedence. Now, your code should look like this:
void allocate_mem(int*** arr, int n, int m)
{
*arr = (int**)malloc(n*sizeof(int*));
for(int i=0; i<n; i++)
(*arr)[i] = (int*)malloc(m*sizeof(int));
}
To understand further what happens in the above code, read this answer.
It is important that you always deallocate dynamically allocated memory explicitly once you are done working with it. To free the memory allocated by the above function, you should do this:
void deallocate_mem(int*** arr, int n){
for (int i = 0; i < n; i++)
free((*arr)[i]);
free(*arr);
}
Additionally, a better way to create a 2D array is to allocate contiguous memory with a single malloc()
function call as below:
int* allocate_mem(int*** arr, int n, int m)
{
*arr = (int**)malloc(n * sizeof(int*));
int *arr_data = malloc( n * m * sizeof(int));
for(int i=0; i<n; i++)
(*arr)[i] = arr_data + i * m ;
return arr_data; //free point
}
To deallocate this memory:
void deallocate_mem(int*** arr, int* arr_data){
free(arr_data);
free(*arr);
}
Notice that in the second technique malloc is called only two times, and so in the deallocation code free is called only two times instead of calling it in a loop. So this technique should be better.
Consider this: Just single allocation
int** allocate2D(int m, int n)
{
int **a = (int **)malloc(m * sizeof(int *) + (m * n * sizeof(int)));
int *mem = (int *)(a + m);
for(int i = 0; i < m; i++)
{
a[i] = mem + (i * n);
}
return a;
}
To Free:
free(a);
If your array does not need to be resized (well, you can, but il will be a bit more complicated), there is an easier/more efficient way to build 2D arrays in C.
Take a look at http://c-faq.com/aryptr/dynmuldimary.html.
The second method (for the array called array2) is quite simple, less painful (try to add the tests for mallocs' return value), and way more efficient.
I've just benchmarked it, for a 200x100 array, allocated and deallocated 100000 times:
- Method 1 : 1.8s
- Method 2 : 47ms
And the data in the array will be more contiguous, which may speed things up (you may get some more efficient techniques to copy, reset... an array allocated this way).
Rather allocating the memory in many different block, one can allocate this in a consecutive block of memory. Do the following:
int** my2DAllocation(int rows,int columns)
{
int i;
int header= rows *sizeof(int *);
int data=rows*cols*sizeof(int);
int ** rowptr=(int **)malloc(header+data);
if(rowptr==NULL)
{
return NULL:
}
int * buf=(int*)(rowptr+rows);
for(i=0;i<rows;i++)
{
rowptr[i]=buf+i*cols;
}
return rowptr;
}
That is an unnecessarily complicated way of allocating space for an array. Consider this idiom:
int main(void) {
size_t m = 4, n = 3;
int (*array)[m];
array = malloc(n * sizeof *array);
free(array);
}