Here is one way to do it. I use a macro for the memory allocation to improve readability. I also defined a couple of pointer types for the same reason. Here's the code :
#define AllocateMemory( count, type ) (type*)calloc( count, sizeof( type ) )
typedef int * PINT;
typedef PINT * PPINT;
int*** AllocateIntMatrix( int nrows, int ncols, int ndeep )
{
int count = 0;
int i, j, k;
int *** m;
m = AllocateMemory( nrows, PPINT );
for( i = 0; i < nrows; ++i )
{
m[ i ] = AllocateMemory( ncols, PINT );
for( j = 0; j < ncols; ++j )
{
m[ i ][ j ] = AllocateMemory( ndeep, int );
}
}
for( i = 0; i < nrows; ++i )
{
for( j = 0; j < ncols; ++j )
{
for( k = 0; k < ndeep; ++k )
{
m[ i ][ j ][ k ] = count;
++count;
}
}
}
return m;
}
Here's code to release the matrix since all well-behaved programs clean up after themselves.
void ReleaseIntMatrix( int *** im, int nrows, int ncols )
{
int i, j;
for( i = 0; i < nrows; ++i )
{
for( j = 0; j < ncols; ++j )
{
free( m[ i ][ j ] );
}
free( m[ i ] );
}
free( m );
};
Note that the functions should allocate the memory they are told to and nothing else. All of those calculations you have should be outside because otherwise the release function would need to calculate them also and it is very bad practice to duplicate code like that. It would be better to have a function to calculate those things. In addition, if you have weird rules for those subscripts, and not starting from zero qualifies as weird, then I recommend that you implement an accessing function analogous to a
Get
method.