1

I've written some code that takes the average of four cells from a 2D array. The conditions are that the columns and rows have to be an even value, if it isn't we ignore the last column/row.

I forgot to mention that this is part of a header file - the 2D array is defined to be a array[x][y] in another file containing the main(). pastebin.com/LUXW5X6b

Given this, I believe the best approach would be to use pointers and malloc to access the heap and make changes. -> How would I go about accomplishing this?

uint8_t *half(const uint8_t array[],
              unsigned int cols,
              unsigned int rows) {
    // your code here
    int i, j;
    uint8_t new_rows = rows / 2;
    uint8_t new_cols = cols / 2;
    uint8_t new_array[new_rows][new_cols];
    if (new_rows % 2 != 0) {
        new_rows = new_rows - 1;
    }
    if (new_cols % 2 != 0) {
        new_cols = new_cols - 1;
    }
    for (i = 0; i < new_rows; i++) {
        for (j = 0; j < new_cols; j++) {
            new_array[i][j] = average(array[2*i][2*j],
                                      array[2*i+1][2*j],
                                      array[2*i+1][2*j+1],
                                      array[2*i][2*j+1]);
        }
    }
    return NULL;
}
1
  • 1
    array[] is 1d .. Commented Mar 28, 2016 at 17:18

1 Answer 1

1

You must declare the argument array as a 2D array. In C99, you can specify the dimensions using this syntax:

uint8_t *half(unsigned int cols, unsigned int rows,
              const uint8_t array[][cols]) {
}

There is another problem: you cannot return a pointer to the local array in automatic storage because this object becomes invalid as soon as the function returns. A simple solution is to allocate the destination array in the caller function and pass to the function half:

int half(unsigned int cols, unsigned int rows,
         const uint8_t array[rows][cols],
         uint8_t output[rows / 2][cols / 2])
{
    unsigned int new_rows = rows / 2;
    unsigned int new_cols = cols / 2;

    for (unsigned int i = 0; i < new_rows; i++) {
        for (unsigned int j = 0; j < new_cols; j++) {
            output[i][j] = average(array[2 * i    ][2 * j    ],
                                   array[2 * i + 1][2 * j    ],
                                   array[2 * i + 1][2 * j + 1],
                                   array[2 * i    ][2 * j + 1]);
        }    
    }
    return 1;
}

Note that arrays are passed as pointers to their first element (they decay into pointers), so the first dimensions in the prototype are simply ignored by the compiler, the above definition is equivalent to:

int half(unsigned int cols, unsigned int rows,
         const uint8_t array[][cols],
         uint8_t output[][cols / 2]) ...

Note also that your extra tests on new_rows and new_cols seem unnecessary as the integer division already rounds toward 0. If the original array has odd dimensions, the reduced array is computed correctly, ignoring the last row and/or column.

Sign up to request clarification or add additional context in comments.

1 Comment

Aye, thank you you made me realize I forgot to detail that the array is predefined in main(). This is my main -pastebin.com/LUXW5X6b

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.