-2

I want to overload operator of stream << for class CMatrix and there is popping out error

"Exception thrown: read access violation.m.matrix was 0xCDDDCDDE."

when it's trying to read m.matrix(debugging stops right there with error).

class CMatrix : IMatrix
{
protected:
    uint32_t rows;
    uint32_t columns;
    double **matrix;
public:
    CMatrix(uint32_t rows, uint32_t columns);
    CMatrix(uint32_t rows, uint32_t columns, double **mat);
~CMatrix();
friend ostream& operator<< (ostream &stream, const CMatrix &m);
}

ostream & operator<<(ostream & stream, const CMatrix & m)
{
    for (int i = 0; i < m.rows; i++)
    {
        for (int j = 0; j < m.columns; j++)
        {
            stream << m.matrix[i][j] << " ";
        }
        stream << endl;
    }
    return stream;
}

CMatrix::CMatrix(uint32_t rows, uint32_t columns, double * mat)
{
    this->rows = rows;
    this->columns = columns;
    double** matrix = new double*[rows];
    for (int i = 0; i<this->rows; i++)
    {
        matrix[i] = new double[columns];
        memcpy(matrix[i], &mat[i * this->columns], sizeof(double)*this->columns);
    }
}
CMatrix::~CMatrix()
{
    for (int i = 0; i < this->rows; i++)                                            
    {
        delete[] matrix[i];                                                 
    }
    matrix = NULL;
}
  • 1
    Relevant: https://stackoverflow.com/questions/370195/when-and-why-will-an-os-initialise-memory-to-0xcd-0xdd-etc-on-malloc-free-new – user0042 Nov 21 '17 at 22:28
  • 2
    Show the code for the constructors. The bug is likely there. – drescherjm Nov 21 '17 at 22:28
  • 1
    The Rule of Three has not been observed. [What is the Rule of Three?](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) Click the link and find out. – user4581301 Nov 21 '17 at 22:34
  • 1
    This is rather a side note of the problem at hand, but you should get in the habit of naming constructor parameters different from class members. For instance if you're using `uint32_t rows;` in your class, your constructor parameters should be something different such as `uint32_t _rows, uint32_t _columns);` Eliminates ambiguity. – Chris Nov 21 '17 at 22:37
  • @PureVision your comment almost nailed the problem. – user4581301 Nov 21 '17 at 23:16

1 Answers1

0

in CMatrix::CMatrix(uint32_t rows, uint32_t columns, double * mat)

double** matrix = new double*[rows];

shadows member

double **matrix;

The constructor allocates and initializes storage that is pointed at by an Automatic (also known as local) variable. This local matrix is lost when the constructor ends, and the member matrix goes uninitialized and points Crom knows where, leading to the crash when it is accessed.

Solution:

CMatrix::CMatrix(uint32_t rows, uint32_t columns, double * mat)
{
    this->rows = rows;
    this->columns = columns;
    matrix = new double*[rows]; // don't create a new variable. Use the member 
    for (int i = 0; i<this->rows; i++)
    {
        matrix[i] = new double[columns];
        memcpy(matrix[i], &mat[i * this->columns], sizeof(double)*this->columns);
    }
}

or better

CMatrix::CMatrix(uint32_t rows, uint32_t columns, double * mat) : 
    rows(rows), columns(columns), matrix(new double*[rows])
{
    for (int i = 0; i<this->rows; i++)
    {
        matrix[i] = new double[columns];
        memcpy(matrix[i], &mat[i * this->columns], sizeof(double)*this->columns);
    }
}

That colon at the end of the parameter list starts a Member Initializer List

However be aware that std::vector will make this job much, much easier by allowing CMatrix to take advantage of the Rule of Zero.

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • It works ! Thank you @user4581301. I've got one more question , how will look like destructor for this?because my old one doesn't work and pops out the same error. I've edited main thread and added destructor. – Wojtek Ptasinski Nov 23 '17 at 15:43
  • @WojtekPtasinski if ` for (int i = 0; irows; i++) { delete[] matrix[i]; } delete[] matrix;` does not work, you have probably run afoul of `CMatrix` not observing [The Rule of Three](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three), but to be sure you should ask a new question. No point muddying the waters on this one. – user4581301 Nov 23 '17 at 16:28