Passing Multidimensional Arrays in C++

By John Paul Mueller, Jeff Cogswell

If you have to pass a multidimensional array to a function, things can get just a bit hairy. That’s because you don’t have as much freedom in leaving off the array sizes as you do with single-dimensional arrays. Suppose you have this function:

int AddAll(int MyGrid[5][6]) {
    int x,y;
    int sum = 0;
    for (x = 0; x < 5; x++) {
        for (y = 0; y < 6; y++) {
            sum += MyGrid[x][y];
        }
    }
    return sum;
}

So far, the function header is fine because we’re explicitly stating the size of each dimension. But you may want to do this:

int AddAll(int MyGrid[][]) {

or maybe pass the sizes as well:

int AddAll(int MyGrid[][], int rows, int columns) {

But unfortunately, when you compile either of these two lines, you get this error:

declaration of 'MyGrid' as multidimensional array
must have bounds for all dimensions except the first

That’s strange: The compiler is telling you that you must explicitly list all the dimensions, but it’s okay if you leave the first one blank, as with one-dimensional arrays.

So that means this crazy thing will compile:

int AddAll(int MyGrid[][6]) {

How about that? The reason is that the compiler treats multidimensional arrays in a special way. A multidimensional array is not really a two-dimensional array, for example; rather, it’s an array of an array.

Thus, deep down inside C++, the compiler treats the statement MyGrid[5][6] as if it were MyGrid[5]where each item in the array is itself an array of size 6. And you’re free not to specify the size of a one-dimensional array. Well, the first brackets represent the one-dimensional portion of the array. So you can leave that space blank, as you can with other one-dimensional arrays.

But then, after that, you have to give the array bounds. And perhaps just a bit contrived. But it’s C++, and it’s the rule: You can leave the first dimension blank in a function header, but you must specify the remaining dimension sizes.

When using multidimensional arrays, it’s often easier if you think of them as an array of arrays. Then you use a typedef so that, instead of it being an array of arrays, it’s an array of some user-defined type, such as GridRow. Either of the following function headers, for example, is confusing:

int AddAll(int MyGrid[][6]) {
int AddAll(int MyGrid[][6], int count) {

Here’s our recommendation: Use a typedef. So here’s a cleaner way:

typedef int GridRow[6];
int AddAll(GridRow MyGrid[], int Size) {
    int x,y;
    int sum = 0;
    for (x = 0; x < Size; x++) {
        for (y = 0; y < 6; y++) {
            sum += MyGrid[x][y];
        }
    }
    return sum;
}

The typedef line defines a new type called GridRow. This type is an array of six integers. Then, in the function, you’re passing an array of GridRows.

Using this typedef is the same as simply using two brackets, except it emphasizes that you’re passing an array of an array — that is, an array in which each member is itself an array of type GridRow.