0

I created a class called Matrix with a 2D array. I can run it with the constructor, copy constructor and destructor. When I introduce the unary negation operator, I get a run time error.

https://gist.github.com/anonymous/7823794

#ifndef MATRIX_H
#define MATRIX_H
class Matrix
{
public:
    Matrix(int rSize=3, int cSize=3);
    Matrix(const Matrix& m);
    ~Matrix();
    bool setValue(int rSize, int cSize, int value);
    bool getValue(int rVal, int cVal, int& value)const;
    const Matrix operator- ();
private:
    int rowSize;
    int columnSize;
    int** arr;
};
#endif



#include<iostream>
#include"Matrix.h"
using namespace std;
Matrix::Matrix(int rSize,int cSize)
{
    columnSize = cSize;
    rowSize = rSize;
    arr = new int* [rowSize];
    for(int i=0; i<rowSize; i++)
        arr[i] = new int[columnSize];
    for(int j=0; j<rowSize; j++)
    {
        for(int k=0; k<columnSize; k++)
            arr[j][k] = 0;
    }

}
Matrix::Matrix(const Matrix& m)
{
    columnSize = m.columnSize;
    rowSize = m.rowSize;
    arr = new int* [rowSize];
    for(int i=0; i<rowSize; i++)
    {
        arr[i] = new int [columnSize];
    }
    for(int i=0; i<rowSize; i++)
    {
        for(int j=0; j<columnSize; j++)
            arr[i][j] = m.arr[i][j];
    }
}
Matrix::~Matrix()
{
    for(int i = 0; i < rowSize; ++i)
        delete [] arr[i];
    delete [] arr;
}
bool Matrix::setValue(int rVal, int cVal, int value)
{
    if((rVal<0)||(cVal<0)||(rVal>rowSize-1)||(cVal>columnSize-1))
        return false;
    arr[rVal][cVal] = value;
    return true;
}
bool Matrix::getValue(int rVal, int cVal, int& value)const
{
    if((rVal<0)||(cVal<0)||(rVal>rowSize-1)||(cVal>columnSize-1))
        return false;
    value = arr[rVal][cVal];
    return true;
}
const Matrix Matrix:: operator- ()
{
    Matrix m(*this);
    for (int i = 0; i< rowSize; i++)
    {
        for(int j=0; j<columnSize; j++)
            m.arr[i][j] = (this->arr[i][j])* -1 ;
    }
    return m;
}





#include<iostream>
#include"Matrix.h"
using namespace std;
void main()
{
    Matrix m(4, 5);
    Matrix m2(m);
    m2.setValue(1,2,12);
    int x;
    m2.getValue(1,2,x);
    Matrix m3;
    m3 = -m2;
}

Edit: Following @unwind and @interjay advice, I implemented the assignment operator first and returned a value, not a reference, for the negation operator and it works. Thank you all for your help

  • 2
    You should paste the code here, so it's available if someone in the distant future sees your post. – kviiri Dec 06 '13 at 13:30
  • @Abhineet Is there an easier way to indent than adding four spaces to each line manually? – FaizHasan123 Dec 06 '13 at 13:51
  • @user3012044 Select the code and press the `{}` button in the toolbar or Ctrl+K. – interjay Dec 06 '13 at 13:53
  • The simple answer is to use `std::vector` rather than managing memory yourself. If you really want to juggle pointers for educational reasons, always remember the [Rule of Three](http://stackoverflow.com/questions/4172722) – Mike Seymour Dec 06 '13 at 14:04
  • Select the text you want to indent and press "CTRL+k". It will automatically indent the codes. – Abhineet Dec 06 '13 at 14:12

2 Answers2

1

Declaring the operator to return const Matrix& and then returning a local variable is wrong. That's a dangling reference, surely?

See for reference this answer where the operator returns an actual new value, not a reference. This makes a lot more sense to me.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
1

You don't have an assignment operator in your class, which will cause double deletion of the member pointer after an assignment (and you're assigning in the line m3 = -m2;).

You should obey the rule of three.

unwind is also correct that the negation operator should return by value: You should never return a reference to a local variable from a function as that leads to undefined behavior.

interjay
  • 107,303
  • 21
  • 270
  • 254
  • Should I also return the'+' and '-' operators by value or can I return those by reference? – FaizHasan123 Dec 06 '13 at 15:01
  • @user3012044 By value. You can't return a local variable or a temporary by reference because it will stop existing when the function returns. – interjay Dec 06 '13 at 16:19