By a "true" 3D array I'm assuming you mean that all the elements are in one contiguous block. In that case your best option would be something like this:
/**
* Allocate an NxRxC array of some arbitrary type T
*/
T (*arr)[R][C] = malloc( sizeof *arr * N );
which gives you
T (*)[R][C] T
+---+ +---+
arr: | | ----------->| | arr[0][0][0]
+---+ +---+
| | arr[0][0][1]
+---+
...
+---+
| | arr[0][0][C-1]
+---+
| | arr[0][1][0]
+---+
...
+---+
| | arr[0][R-1][C-1]
+---+
| | arr[1][0][0]
+---+
...
You would only use a triple pointer for a piecemeal, "jagged" array allocation (error checking omitted for brevity):
T ***a = malloc( sizeof *a * N )
for ( size_t i = 0; i < N; i++ )
{
a[i] = malloc( sizeof *a[i] * R );
for ( size_t j = 0; j < C; j++ )
{
a[i][j] = malloc( sizeof *a[i][j] * C );
}
}
which gives you something like this:
T *** T** T* T
+---+ +---+ +---+ +---+---+---+---+---+
a: | |------>| | a[0] ----->| | a[0][0] ---->| | | | | |...
+---+ +---+ +---+ +---+---+---+---+---+
| | a[1] --+ | | a[0][1] --+
+---+ | +---+ | +---+---+---+---+---+
... | ... +->| | | | | |...
| +---+---+---+---+---+
|
| +---+ +---+---+---+---+---+
+-->| | a[1][0] ---->| | | | | |...
+---+ +---+---+---+---+---+
| | a[1][1] --+
+---+ | +---+---+---+---+---+
... +->| | | | | |...
+---+---+---+---+---+
You would use this second method when rows don't have to be the same length, or when you absolutely cannot allocate the whole array in a single contiguous block.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…