4

Please take a look at the code below:

#include <iostream>
using namespace std;

int main(){

    char matrix[2][2][2];

    return 0;
}

int getMatrixData(char matrix[][2][2], int x, int y, int z) {
    return matrix[x][y][z];
}

When matrix 3d array passed in as a parameter into a function, why is it ok not to specify the first [] size? How this missing dimension can be explained?

Mohit Jain
  • 29,414
  • 8
  • 65
  • 93
  • 1
    This is what your compiler should have said: `error: array has incomplete element type 'char []'`. Maybe you meant `char matrix[][2][2]`? – juanchopanza Feb 23 '17 at 07:18

2 Answers2

4

Your code is syntactically incorrect. Assuming you meant int getMatrixData(char matrix[][2][2], int x, int y, int z).

When you pass array arguments to function, array decays to pointer to first element (type char [2][2] in this case). Now some syntax of array and pointer are similar so you don't find much difference.

When multidimensional array is passed, for example 3d in your case, it can be seen as array of 2-d arrays. So you need to give the type of each element char [2][2] in your case and you can skip the dimension of final array as it will decay to pointer anyway. char [2][2] is the information compiler needs to compute the offset of each element.

offset of matrix[x][y][z] = base address of matrix +
                            x * sizeof(char [2][2]) +
                            y * sizeof(char [2]) +
                            z

If you don't pass the dimensions of initial element, compiler can't resolve sizeof in above equation. Passing skipped dimension is optional.

Community
  • 1
  • 1
Mohit Jain
  • 29,414
  • 8
  • 65
  • 93
0

In c++ I would use multidimensional arrays in a different way. There are many topics on the internet about it.

This topic explains how you could do it using a char***. E.g.:

char getMatrixData(char*** matrix, int x, int y, int z)
{
    return matrix[x][y][z];
}

int main()
{
    char ***matrix = new char**[2];
    for (auto i = 0; i < 2; i++)
    {
        matrix[i] = new char*[2];
        for (auto j = 0; j < 2; j++)
        {
            matrix[i][j] = new char[2];
        }
    }

    getMatrixData(matrix, 1, 1, 1);

    // N.B.! you should normally free the memory using delete []!!
    // But in this case the program ends, so the memory is freed anyhow.

    return 0;
}

But you could also use the std::vector type

#include <vector>
using std::vector;

using CharVector1D = vector<char>;
using CharVector2D = vector<CharVector1D>;
using CharVector3D = vector<CharVector2D>;

char getMatrixData(CharVector3D const& matrix, int x, int y, int z)
{
    return matrix[x][y][z];
}

int main()
{
    CharVector3D matrix(2, CharVector2D(2, CharVector1D(2)));

    getMatrixData(matrix, 1, 1, 1);

    return 0;
}

However, c++ is supposed to be an object oriented programming language. So it is probably better to define an matrix object.

#include <vector>
using std::vector;

template <class T>
class Matrix3D
{
private:
    size_t _sizeX;
    size_t _sizeY;
    size_t _sizeZ;
    vector<T> _data;

public:
    Matrix3D(size_t const x_size, size_t const y_size, size_t const z_size)
        : _sizeX(x_size)
        , _sizeY(y_size)
        , _sizeZ(z_size)
        , _data(vector<T> (x_size*y_size*z_size))
    {}

    T GetData(size_t const x, size_t const y, size_t const z) const
    {
        return _data.at(x + (_sizeX * (y + (_sizeY * z))));
    }
};

int main()
{
    Matrix3D<char> matrix(2, 2, 2);

    matrix.GetData(1, 1, 1);

    return 0;
}
Community
  • 1
  • 1
JHBonarius
  • 6,889
  • 3
  • 12
  • 28