A possible way could be to allocate a mono-dimensional array, e.g.
int width=10; length=20; height=50;
char* arr = malloc(width*length*height);
if (!arr) { perror("malloc"); exit(EXIT_FAILURE); };
then have some way to access it, for instance a macro
#define Element(I,J,K) arr[width*length*(I)+length*(J)+(K)]
and use Element(i,j,k)
You could pack all this using a flexible array member like
struct my3dstring_st {
int width;
int length;
int height;
char arr[];
};
then have a.g. a making function
struct my3dstring_st *
make_my3dstring (int width, int length, int height)
{
if (width<=0 || length<=0 || height<=0) return NULL;
struct my3dstring_st* s =
malloc(sizeof(struct my3dstring_st)
+ width * length * height);
if (!s) {perror("malloc"); exit(EXIT_FAILURE); };
s->width = width;
s->length = length;
s->height = height;
memset (s->arr, 0, width * length * height);
return s;
}
and an inline accessing function (in a header file):
static inline int
access_m3dstring(struct my3dstring_st*s, int i, int j, int k) {
if (!s || i<0 || j<0 || k<0
|| i>=s->width || j>=s->height || k>=s->length) return EOF;
return s->arr[i*->width*s->height + j*s->height + k];
}
I leave as an exercise to write the modification function modify_m3dstring
, and you could have unsafe but faster variants which don't do any checks...