2

This is a minimal reproducable example of the problem. Having height and length as parameters (rather than calculate them) is deliberate.

typedef struct
{
    int red;
} triple;

int main(void)
{
    triple array[3][3] = {
      { {.red = 10}, {.red = 40}, {.red = 70}},
      { {.red = 110}, {.red = 120}, {.red = 130}},
      { {.red = 200}, {.red = 220}, {.red = 240}}
    };

printarray(2, 2, array);
}


void printarray(int height, int length, triple array[][length])
{
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < length; j++)
        {
            printf("red score at array[%i][%i] = %i\n", i, j, array[i][j].red);
        }
    }
}

The output I get is:
red score at array[0][0] = 10
red score at array[0][1] = 40
red score at array[1][0] = 70
red score at array[1][1] = 110

But I would expect:
red score at array[0][0] = 10
red score at array[0][1] = 40
red score at array[1][0] = 110
red score at array[1][1] = 120

The indexing of the 2d array is clearly not working as I expect, but why?

Listya
  • 23
  • 4

2 Answers2

3

You are passing 2,2 to printarray. This is height,length.

But, the array is defined with a length of 3. So, you must pass 3 to printarray as the length.

Otherwise, the indexing in printarray is incorrect. As you have it, the array within printarray is equivalent to triple array[2][2] and not triple array[3][3] as is required.

The height can be less than the defined height, but length must match. Here, length is the stride. This is the number of elements in a given row.

So, in main, call with: printarray(3,3,array)


If you truly wish to print a subsection of the array, you'd need to pass a separate variable to printarray for the stride.

The function would have to be declared as:

void printarray(int height, int length, int stride, triple array[][stride])

Then, in main, call it with:

printarray(2,2,3,array);
Craig Estey
  • 30,627
  • 4
  • 24
  • 48
2

The problem is in your call to printarray:

printarray(2, 2, array);

where you tell the function that the array has two rows and two columns - but it doesn't, it has three rows and three columns. The compiler assumes that you don't tell it lies!

You must call your function with the correct value of the length parameter, as this is used by the compiler to deduce how to calculate the offsets for an element array[i][j].

If you only want to then print part of that array, you should specify the number of columns and rows to print as extra parameters to your function, like this:

void printarray(int height, int length, int nrows, int ncols, triple array[][length])
{
    if (nrows > height) nrows = height;
    if (ncols > width) ncols = width;   // Prevent error conditions!
    for (int i = 0; i < nrows; i++) {
        for (int j = 0; j < ncols; j++) {
            printf("red score at array[%i][%i] = %i\n", i, j, array[i][j].red);
        }
    }
}

and then call the function like this:

    printarray(3, 3, 2, 2, array);

Note: You are also missing a function prototype for printarray before its use, which will be an error on some compilers (but only a warning on others); add this line somewhere before your main function:

void printarray(int height, int length, int nrows, int ncols, triple array[][length]);
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83