Plain old declaration (don't do this):
try
{
float *** f = new float ** [2];
for (size_t i = 0; i < 2; i++)
{
f[i] = new float * [3];
for (size_t j = 0; j < 3; j++)
f[i][j] = new float[4];
}
} catch(const std::exception & e) { /* This is a pain to deal with to avoid any leak */ }
// Now you can access via f[0][1][2]
// delete[] in reverse order.
A bit better (avoid using many allocations):
try
{
typedef float BigArray[3][4];
BigArray * f = new BigArray[2];
} catch(const std::exception & e) { /* here it's simple */ }
// delete with delete[] f
A bit cumbersome, but you don't care about memory leak anymore:
std::vector<std::vector<std::vector<float>>> f(2, std::vector<std::vector<float>>(3, std::vector<float>(4)));
// Use with f[0][1][2]
Also, as most would say, instead of pointer to pointer to pointer of float, you should store your array in pointer to float instead, it'll be a lot more efficient since you don't need to dereference in 3 steps to access an element, that is, like:
int vectorElems = 4, columns = 3, rows = 2;
int rowStride = vectorElems * columns;
float * f = new float[rows*columns*vectorElems];
// Access with stride:
f[0 * rowStride + 1 * vectorElems + 2] = 3.14f;
// Delete with delete[] f
There are also template matrix classes (for exemple in opencv) that's doing this properly by providing an overloaded () operator so you can access the object like f(0, 1, 2)