-2

I am currently building a median filter in C++. I have a decent amount of experience with other languages but C++ and its pointers confuse me. I am building a function which takes in a 2D array of RGB values of an image. The function may not be 100% yet but I just cannot get past returning the 2d array. My input parameters is the row major version of the image array and the filter size and the output is the pointer to the filtered 2D array. It has the following error when debugging >"Cannot convert 'int (*)[size]' to 'int" Can you possibly walk me through this error and how to deal with it? Also if you spot any other peculiarities please mention it, it would be greatly appreciated!

int** seq_medFilter(int image[][3], int filter)
{
   int output[640 * 480][3];
   int rows = 640;
   int cols = 480;
   int fil_arr_size = pow((2 * filter + 1), 2);
   for (int i = 0; i<rows*cols; ++i)
   {
       int temp[fil_arr_size][3];
       //edge cases excluded
       int current_col = i / cols;
       int current_row = i%cols;

       if (current_col < filter || current_col > cols - filter - 1 || current_row < filter || current_row > rows - filter - 1)
       {
           for (int j = 0; j<3; j++) {
               output[i][j] = image[i][j];
           }
       }
       else
       {
           // just for a filter size of one now
           int pos_x = i / cols - filter;
           int pos_y = i%cols - filter;
           for (int x = 0; x< fil_arr_size - 1; ++x)
           {
               for (int j = 0; j<3; j++) {
                   temp[x][j] = image[pos_x*cols + pos_y][j];
               }
               pos_x += 1;
               if (pos_x == (2 * filter + 1))
               {
                   pos_x = pos_x - (2 * filter + 1);
                   pos_y += 1;
               }
           }
           int N = sizeof(temp) / sizeof(temp[0]);
           sort(temp, temp + N);
           for (int j = 0; j<3; j++) {
               output[i][j] = temp[N / 2][j];
           }
       }
   }
   return output;
}

int main()
{
   return 0;
}
wohlstad
  • 12,661
  • 10
  • 26
  • 39
RavoDavo
  • 1
  • 1
  • 1
    You can't return `output` like this. Firstly, it's a local variable. You **should** use a `std::vector>` or similar. – ChrisMM May 09 '22 at 16:49
  • `int temp[fil_arr_size][3];` is problematic - VLA are not a part of c++ standard (even if some compilers support it: https://stackoverflow.com/questions/39334435/variable-length-array-vla-in-c-compilers). Using `std::vector` as suggested above avoids this problem. Also you should cast the result from `pow` to int before assigning to `fil_arr_size` (or find an alternative). – wohlstad May 09 '22 at 16:53
  • Avoid C-style pointers or C-style arrays. They are a low-level features of C++. This code has about four different errors concerning pointers and arrays, perhaps more. Learn about std::vector and std::array. – n. m. could be an AI May 09 '22 at 17:27

1 Answers1

0

The issue is that you cannot return a int output[][] as an int **. They are considered different types, but also, output is a local variable, and thus cannot be returned as a pointer without causing UB.

You could use a vector instead, like so:

std::vector<std::vector<int>> seq_medFilter(int image[][3], int filter)
{
   std::vector<std::vector<int>> output( 640 * 480, std::vector<int>( 3 ) );
   //...

If you insist on using pointers, then you can used unique_ptr/shared_ptr, or use new, though I would say that all three of these options are worse than just using a vector here.

You could also use an std::array

Example:

std::array<std::array<int, 3>, 640*480> seq_medFilter(int image[][3], int filter)

Then, where you declare output, you would change its type to

std::array<std::array<int, 3>, 640*480> output;

Note that the line:

int temp[fil_arr_size][3];

Is not valid in standard C++ (see here).

For completeness, using the pointer method, you would keep your function head the same, but then use:

   int **output = new int*[640*480];
   for ( size_t idx = 0; idx < 640*480; ++idx ) {
       output[idx] = new int[3];
   }

Again, I don't recommend this method.

ChrisMM
  • 8,448
  • 13
  • 29
  • 48