Home > Net >  No matching function when calling the function
No matching function when calling the function

Time:11-22

I am a newbie to C and I wanted to know what should I do. I need to write a program where the user will be filling the 2d array. I need to program to show the 2d array in the form of matrix and do some other things, like counting elements that are not 0. But I am stuck. I can't call functions in main(), because there is no matching call error. I suppose this is because of the array initializing, but I saw people on the internet who does

int arr[row][col];

Code:

#include <iostream>
#include <conio.h>
#include <iomanip>
using namespace std;


// for filling the 2d array
void fillTheMatrix(int **arr, int row, int col) {
    cout << "Please, enter here the elements you want to use for the matrix A:\n";
    for (int i = 0; i < row; i  ) {
        for (int j = 0; j < col; j  ) {
            cout << "a[" << i << "][" << j << "] = ";
            cin >> arr[i][j];
        }
    }
}

// for viewing this s2d array as matrix
void theMatrixView(int **arr, int row, int col) {
    cout << "The matrix A\n";
    for (int i = 0; i < row; i  ) {
        for (int j = 0; j < col; j  ) {
            cout << setw(3) << arr[i][j] << "\t";
        }
        cout << endl;
    }
}


int main() {
    int row;
    int col;

    cout << "Please, enter the number of rows of the matrix A: " << endl;
    cin >> row;
    cout << "Please, enter the number of columns of the matrix A: " << endl;
    cin >> col;

    int arr[row][col];

    // TASK 1
    fillTheMatrix(arr, row, col); // No matching function for call to 'fillTheMatrix'
    theMatrixView(arr, row, col); // // No matching function for call to 'theMatrixView'

    return 0;

}

Can you help me fixing this problem? I would be glad to have any recommendations to refactor code.

CodePudding user response:

As suggested in the comments better way is to use std::vector, however if you really want to use raw C arrays, to have a correctly type passed in, you need to declare a pointer to pointers to dynamically allocated memory:

int** arr = new int*[row];
for (int i = 0; i < row;   i)
{
    for (int j = 0; j < col;   j)        
        arr[i] = new int[col];        
}

fillTheMatrix(arr, row, col); 
theMatrixView(arr, row, col); 

for (int i = 0; i < row;   i)
{
    delete[] arr[i];        
}

CodePudding user response:

You used a so called VLA. A variable length array. In C this is perfectly fine. See here.

In C this is not allowed. Arrays in C must have a size which is known at compile time. So, a literal number, like 3. Or a const or, in C now a constexpr.

Some compilers allow VLA also while compiling C program. We call this a "compiler extension". But if you follow strict C rules, it will result in an error.

To give you an alternative you can use the std::vector in C . It hast the additional advantage that it knows its size. So, no need to pass “row” and “col” to all sub routines.

And, in C you should not use C-Style arrays at all. And even the use of new and raw pointers for owned memory is discourages. Simply std::vector. It is easy.

We will pass the 2d vector via reference to the sub-functions to avoid copying.

Please see:

#include <iostream>
#include <vector>
#include <conio.h>
#include <iomanip>
using namespace std;

// To save typing work
using IntVec2d = std::vector<std::vector<int>>;

// for filling the 2d array
void fillTheMatrix(IntVec2d& arr) {
    cout << "Please, enter here the elements you want to use for the matrix A:\n";
    for (int i = 0; i < arr.size(); i  ) {
        for (int j = 0; j < arr[i].size(); j  ) {
            cout << "a[" << i << "][" << j << "] = ";
            cin >> arr[i][j];
        }
    }
}

// for viewing this s2d array as matrix
void theMatrixView(IntVec2d& arr) {
    cout << "The matrix A\n";
    for (int i = 0; i < arr.size(); i  ) {
        for (int j = 0; j < arr[i].size(); j  ) {
            cout << setw(3) << arr[i][j] << "\t";
        }
        cout << endl;
    }
}

int main() {
    int row;
    int col;

    cout << "Please, enter the number of rows of the matrix A: " << endl;
    cin >> row;
    cout << "Please, enter the number of columns of the matrix A: " << endl;
    cin >> col;

    IntVec2d arr;

    // TASK 1
    fillTheMatrix(arr); // No matching function for call to 'fillTheMatrix'
    theMatrixView(arr); // // No matching function for call to 'theMatrixView'
}

CodePudding user response:

Leaving out the fact that you're trying to initialize a VLA, your issue comes from the fact that you are trying to pass an int[][] into a int**.

It seems you're believing this to be possible due to the fact that an int[] can be passed to a int* parameter. but an int[] != int* rather single dimension arrays go through array to pointer decay: In places where a pointer type is expected, an array type will be implicitly converted to a pointer type pointing to the first element of the array, int arr[10] will be converted to int *arr with value &(arr[0]).

In the case of a multidimensional array, array to pointer decay still does the same thing: int arr[10][5] implicitly converts to: int(*arr)[5], with value: &(arr[0]) which is the address of the first element of the first dimension.

As other answers have recommended use std::vector<std::vector<int>> arr.

All of what i've talked about is explained in more detail here

  •  Tags:  
  • c
  • Related