0

I am writing a Qt application for matrix arithmetic . I taken input of 2 3x3 arrays in x1 and y1 if int is selected and in x2 and y2 if float is selected . Have a look at MainWindow.cpp .

MainWindow.cpp

int x1[3][3],y1[3][3];
float x2[3][3],y2[3][3];
matrix<int> m1 ;
matrix<float> m2 ;
void MainWindow::addcheck(){
    typecheck();
    if(ui->intradio->isChecked()){
        int** add1 = m1.add(x1,y1);
        putresult1(add1);
    }
    else if(ui->floatradio->isChecked()){
        int** add2 = m2.add(x2,y2);
        putresult2(add2);
    }
}

I am passing these 2 arrays in add function of the matrix class as shown below .

matrix.h

template <class T>
class matrix
{
public:
    matrix();
    T** subtract(T**&,T**&);
    T** add(T**&,T**&);
    T** multiply(T**&,T**&);
};

matrix.cpp

template <class T>
T** matrix<T>::add(T**& a, T**& b) {
    T c[3][3] ;
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            c[i][j] = a[i][j] + b[i][j] ;
        }
    }
    return c ;
}

However, Im recieving the following error while returning the 2d array to ** . Im unable to decrypt the error . Error:

/Users/sarthakmunshi/prac/mainwindow.cpp:74: error: non-const lvalue reference to type 'int **' cannot bind to a value of unrelated type 'int [3][3]'
        add1 = m1.add(x1,y1);
                      ^~
/Users/sarthakmunshi/prac/matrix.h:10: passing argument to parameter here
    T** add(const T**&,const T**&);
                      ^
12
  • 1
    why a reference to a pointer-to-pointer T**&? Commented Apr 22, 2015 at 10:39
  • 4
    please don't do this. Use std::vector<std::vector<int>> instead. Commented Apr 22, 2015 at 10:39
  • 1
    std::vector<std::vector>> is not appropriate to matrices. You don't have the guarantee that all the lines have the same size ! The best way to manage mathematical matrices is to use only one vector of n x m values and manage accesses to point the good address (as in blas/lapack) Commented Apr 22, 2015 at 10:42
  • 1
    You are returning a variable 'c' from your 'add' method. You mustn't do it, 'c' is created on stack and when it goes out of scope you can't rely on it. Commented Apr 22, 2015 at 10:43
  • 3
    Any decent matrix implementation would store the rows sequentially in a one dimensional array of size m*n. Unless the size is static, in which case there is no need for indirection. Commented Apr 22, 2015 at 10:44

1 Answer 1

3

Regardless of what you may have heard before, arrays are not pointers. A bidimensional array has little to do with a pointer to a pointer, which is your compile issue: there is no way of getting from a 2D array to a pointer-to-pointer.

If your arrays are fixed size, you can change the signature of the functions to require it (and incidentally build, which is good, right?):

?? add(T (&a)[3][3], T (&b)[3][3]);

but you are left with what to return from there... of course the answer is Matrix<T>, right? Adding two matrices returns a matrix, which would indicate that the function you are looking for is more like (as a free function):

template <typename T>
Matrix<T> add(Matrix<T> const & lhs, Matrix<T> const & rhs);

Which, of course can be spelled:

template <typename T>
Matrix<T> operator+(Matrix<T> const & lhs, Matrix<T> const & rhs);

I would recommend that you create a minimal matrix class (google, you can see many reference implementations) or that you use one from an existing library.

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

4 Comments

Isn't there a rudimentary way of simply passing a 2d array to a method, calculating and then returning it back to another 2d array ?
@saru95: You can pass an array by reference (or pointer), but the problem would be what to return. Either you return a pointer/reference to one of the arguments (you could have add mean += and modify the first argument in place) or you need to create an array... arrays cannot be passed or returned by value in the language, which means that you would need to dynamically allocate and return a pointer complicating lifetime for the users... arrays are not really first class citizens in C or C++
Oh ! are you suggesting i cange c[3][3] in my code to dynamically allocated version !?
@saru95: No, I am suggesting not to do that. I am suggesting that you make Matrix a real matrix (holds data) and work in terms of Matrix objects rather than plain arrays. Yes, by dynamically allocating the arrays you can manage to get something that builds and works... and is quite hard to use correctly and easy to use incorrectly; don't go there.

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.