To access elements of array you need to allocate memory: either on stack(like below) or in static memory (globals, syntax the same as for stack) or in heap (using new operator. Then do not forget to delete memory in the end of usage of array. Or use smart pointers). Using std::vector is less error prone.
typedef float A2D[2][3]; // declaration of type
A2D a1 = {{42, 3, 0}, {-1, 5, 9}}; // definition of 2D array with initialization
A2D a2 = {{1, 3, 0}, {-1, 5, 9}};
A2D * arrayOfPointers[2] = {&a1, &a2}; // definition of array of pointers to 2D arrays with initialization
float f1 = (*(arrayOfPointers[0]))[0][0]; // accessing element
float f2 = (*(arrayOfPointers[0]))[0][1];
float f3 = (*(arrayOfPointers[0]))[1][1];
assert(f1 == 42);
assert(f2 == 3);
assert(f3 == 5);
If you need to define dimensions of array in run time or lifecycle of array is longer than lifecycle of function where you define array then you need to allocate array in heap.
A dynamic 2D array is basically an array of pointers to arrays. You can initialize it using a loop.
int rowCount = 2;
int colCount = 3;
float** da1 = new float*[rowCount];
for(int i = 0; i < rowCount; ++i)
da1[i] = new float[colCount];
for(int i = 0; i < rowCount; ++i)
{
for(int j = 0; j < colCount; ++j)
{
da1[i][j] = a1[i][j];
}
}
float** da2 = new float*[rowCount];
for(int i = 0; i < rowCount; ++i)
da2[i] = new float[colCount];
for(int i = 0; i < rowCount; ++i)
{
for(int j = 0; j < colCount; ++j)
{
da2[i][j] = a2[i][j];
}
}
float** arrayOfPointersDyn[2] = {da1, da2};
{
float f1 = (arrayOfPointersDyn[0])[0][0];
float f2 = (arrayOfPointersDyn[0])[0][1];
float f3 = (arrayOfPointersDyn[0])[1][1];
assert(f1 == 42);
assert(f2 == 3);
assert(f3 == 5);
}