I suggest the following way to allocate the array, so as to have all elements contiguous in memory :
int n;
char** array2d=malloc(n*sizeof(char*));
if(array2d==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
array2d[0]=malloc(n*n*sizeof(char));
if(array2d[0]==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
int i;
for (i = 1 ; i < n ; i++)
{
array2d[i] =& array2d[0][i*n];
}
The elements can be acceded by array2d[i][j]
.
A 2D array is an array of pointers to starts of rows, all items being allocated by a single call to malloc()
.
This way to allocate memory is useful if the data is to by treated by libraries such as fftw or lapack. The pointer to the data is array[0]
.
Indeed, writing array2d[0][n]=42
or array2d[1][0]=42
performs the same thing !
See :
In a function :
int alloc2d(int n,char ***array2d){
*array2d=malloc(n*sizeof(char*));
if(*array2d==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
(*array2d)[0]=malloc(n*n*sizeof(char));
if((*array2d)[0]==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
int i;
for (i = 1 ; i < n ; i++)
{
(*array2d)[i] =& (*array2d)[0][i*n];
}
return 0;
}
called from main by char** array2d;alloc2d(42,&array2d);
Test code :
#include <stdio.h>
#include <stdlib.h>
int alloc2d(int n,char ***array2d){
*array2d=malloc(n*sizeof(char*));
if(*array2d==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
(*array2d)[0]=malloc(n*n*sizeof(char));
if((*array2d)[0]==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
int i;
for (i = 1 ; i < n ; i++)
{
(*array2d)[i] =& (*array2d)[0][i*n];
}
}
int free2d(char **array2d){
free(array2d[0]);
free(array2d);
return 0;
}
int main()
{
int n=42;
char** array2d;
alloc2d(n,&array2d);
array2d[0][n]=13;
printf("%d\n",array2d[1][0]);
free2d(array2d);
return 0;
}
Compiled by gcc main.c -o main
. As expected, output is 13. A function to free the memory was added.