I have to assign memory to a 3D array using a triple pointer.
#include
int main()
{
int m=10,n=20,p=30;
char ***z;
z = (char***)
If you don't need the memory to be allocated in a single, contiguous chunk (which IME is the usual case), you would do something like this:
char ***z;
z = malloc(sizeof *z * m); // allocate m elements of char **
if (z)
{
int i;
for (i = 0; i < m; i++)
{
z[i] = malloc(sizeof *z[i] * n); // for each z[i],
if (z[i]) // allocate n elements char *
{
int j;
for (j = 0; j < n;j++)
{
z[i][j] = malloc(sizeof *z[i][j] * p); // for each z[i][j],
if (z[i][j]) // allocate p elements of char
{
// initialize each of z[i][j][k]
}
}
}
}
}
Note that you will need to free this memory in reverse order:
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
free(z[i][j];
free(z[i]);
}
free(z);
If you really need the memory to be allocated in a contiguous chunk, you have a couple of choices. You could allocate a single block and compute your offsets manually:
char *z = malloc(sizeof *z * m * n * p); // note type of z!
...
z[i * m + j * n + k] = some_value();
When you're done, you just need to do a single free
:
free(z);
If you have a C99 compiler or a C11 compiler that supports variable-length arrays, you could do something like this:
int m=..., n=..., p=...;
char (*z)[n][p] = malloc(sizeof *z * m);
This declares z
as a pointer to an n
xp
array of char
, and we allocate m
such elements. The memory is allocated contiguously and you can use normal 3-d array indexing syntax (z[i][j][k]
). Like the above method, you only need a single free
call:
free(z);
If you don't have a C99 compiler or a C11 compiler that supports VLAs, you would need to make n
, and p
compile-time constants, such as
#define n 20
#define p 30
otherwise that last method won't work.
Edit
m
doesn't need to be a compile-time constant in this case, just n
and p
.
You would need the following nested loop -
z = (char**)malloc(sizeof(char*) * m);
for (int i = 0; i < m; ++i)
{
*(z + i) = (char*)malloc(sizeof(char*) * n);
for (int j = 0; j < n; ++j)
{
*(*(z + i)) = (char)malloc(p);
}
}
May not be synactically accurate, but it should be something along these lines.
You want sizeof(char)
not sizeof(char**)
as the latter will give you the size of a pointer which on most modern systems will be 4 bytes instead of the 1 you're expecting.
There's no need to cast the return value of malloc()
, in C.
And if you expect to store m * n * p
characters directly (and compute the address yourself), then you should of course not scale the allocation by the size of a char **
.
You mean:
int m = 10, n = 20, p = 30;
char *z = malloc(m * n * p * sizeof *z);
This will allocate 10 * 20 * 30 = 6000 bytes. This can be viewed as forming a cube of height p
, with each "slice" along the vertical axis being n * m
bytes.
Since this is for manual addressing, you cannot use e.g. z[k][j][i]
to index, instead you must use z[k * n * m + j * m + i]
.
To completely allocate a 3D dynamic array you need to do something like the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m=10,n=20,p=30;
char ***z;
z = malloc(m * sizeof(char **));
assert(z != NULL);
for (i = 0; i < m; ++i)
{
z[i] = malloc(n * sizeof(char *));
assert(z[i] != NULL);
for (j = 0; j < n; ++j)
{
z[i][j] = malloc(p);
assert(z[i][j] != NULL);
}
}
return 0;
}
Freeing the data is left as an exercise for the reader.