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.