Possible Duplicates:
Malloc a 3-Dimensional array in C?
dynamic allocation/deallocation of 2D & 3D arrays
How can i allocate 3D arrays using malloc?
Possible Duplicates:
Malloc a 3-Dimensional array in C?
dynamic allocation/deallocation of 2D & 3D arrays
How can i allocate 3D arrays using malloc?
There are two different ways to allocate a 3D array. You can allocate it either as a 1D array of pointers to a (1D array of pointers to a 1D array). This can be done as follows:
int dim1, dim2, dim3;
int i,j,k;
double *** array = (double ***)malloc(dim1*sizeof(double**));
for (i = 0; i< dim1; i++) {
array[i] = (double **) malloc(dim2*sizeof(double *));
for (j = 0; j < dim2; j++) {
array[i][j] = (double *)malloc(dim3*sizeof(double));
}
}
Sometimes it is more appropriate to allocate the array as a contiguous chunk. You'll find that many existing libraries might require the array to exist in allocated memory. The disadvantage of this is that if your array is very very big you might not have such a large contiguous chunk available in memory.
const int dim1, dim2, dim3; /* Global variables, dimension*/
#define ARR(i,j,k) (array[dim2*dim3*i + dim3*j + k])
double * array = (double *)malloc(dim1*dim2*dim3*sizeof(double));
To access your array you just use the macro:
ARR(1,0,3) = 4;
void * as returned by malloc & friends in C. 2) double *** etc. is not a 3D array and it cannot be used as one! It only happens to use the same syntax as one uses for 3D array when indexing an entry, but has very different semantics as the complicated nested allocation already shows.This would work
int main()
{
int ***p,i,j;
p=(int ***) malloc(MAXX * sizeof(int **));
for(i=0;i<MAXX;i++)
{
p[i]=(int **)malloc(MAXY * sizeof(int *));
for(j=0;j<MAXY;j++)
p[i][j]=(int *)malloc(MAXZ * sizeof(int));
}
for(k=0;k<MAXZ;k++)
for(i=0;i<MAXX;i++)
for(j=0;j<MAXY;j++)
p[i][j][k]=<something>;
}
void * as returned by malloc & friends in C. 2) double *** etc. is not a 3D array and it cannot be used as one! It only happens to use the same syntax as one uses for 3D array when indexing an entry, but has very different semantics as the complicated nested allocation already shows.array = malloc(num_elem * num_elem * num_elem * sizeof(array_elem));
Why not? :)
If somebody still wants to use 3-dimensional array allocated in one big chunk, here's how you add normal indexing to it:
void*** newarray(int icount, int jcount, int kcount, int type_size)
{
void*** iret = (void***)malloc(icount*sizeof(void***)+icount*jcount*sizeof(void**)+icount*jcount*kcount*type_size);
void** jret = (void**)(iret+icount);
char* kret = (char*)(jret+icount*jcount);
for(int i=0;i<icount;i++)
iret[i] = &jret[i*jcount];
for(int i=0;i<icount;i++)
for(int j=0;j<jcount;j++)
jret[i*jcount+j] = &kret[i*jcount*kcount*type_size+j*kcount*type_size];
return iret;
}
void * as returned by malloc & friends in C. 2) double *** etc. is not a 3D array and it cannot be used as one! It only happens to use the same syntax as one uses for 3D array when indexing an entry, but has very different semantics as the complicated nested allocation already shows.For a given type T (non-contiguous):
size_t dim0, dim1, dim2;
...
T ***arr = malloc(sizeof *arr * dim0); //type of *arr is T **
if (arr)
{
size_t i;
for (i = 0; i < dim0; i++)
{
arr[i] = malloc(sizeof *arr[i] * dim1); // type of *arr[i] is T *
if (arr[i])
{
size_t j;
for (j = 0; j < dim1; j++)
{
arr[i][j] = malloc(sizeof *arr[i][j] * dim2);
}
}
}
}
Unless you are working with a very old (pre-C89) implementation, you do not need to cast the result of malloc(), and the practice is discouraged. If you forget to include stdlib.h or otherwise don't have a prototype for malloc() in scope, the compiler will type it to return int, and you'll get an "incompatible type for assignment"-type warning. If you cast the result, the warning is suppressed, and there's no guarantee that a conversion from a pointer to an int to a pointer again will be meaningful.
double *** etc. is not a 3D array and it cannot be used as one! It only happens to use the same syntax as one uses for 3D array when indexing an entry, but has very different semantics as the complicated nested allocation already shows.