0

I'm developing a C++ project for matrices objects and operations with it. For this I design a DoubleMatrix class which has three attributes: number of rows, number of columns and the matrix data itself. The header file of my class is the following:

#ifndef DOUBLE_MATRIX_H
#define DOUBLE_MATRIX_H
#include <functional>

class DoubleMatrix final
{
    double** mMatrixData;
    int mRows;
    int mColumns;
    typedef std::function<void(int&, int&, double&)> matrixElem;
public:

    DoubleMatrix(int rows, int cols);
    ~DoubleMatrix();

    inline double& get(int& m, int& n) const ;
    inline void set(int m, int n, double value) const;
    DoubleMatrix transpose() const;
    void print() const
    void forEachRowNColumn(const std::function<void(int&, int&, double&)>& block) const;
};
#endif

I'm not sure if double** mMatrixData is the best option for save my matrix data, but is working well, I think.

The source file is presented below:

#include "DoubleMatrix.h"
#include <iostream> 

DoubleMatrix::DoubleMatrix(const int rows, const int cols)
{
    mRows = rows;
    mColumns = cols;
    mMatrixData = new double*[mRows];
    for (int i = 0; i < mRows; i++)
        mMatrixData[i] = new double[mColumns];  

    for (int i = 0; i < mRows; i++)
        for (int j = 0; j < mColumns; j++)
            mMatrixData[i][j] = 0.0;
}   

DoubleMatrix::~DoubleMatrix()
{
    delete[] mMatrixData;
}   

inline double& DoubleMatrix::get(int& m, int& n) const
{
    return mMatrixData[m][n];
}   

inline void DoubleMatrix::set(const int m, const int n, const double value) const
{
    mMatrixData[m][n] = value;
}   

DoubleMatrix DoubleMatrix::transpose() const
{
    DoubleMatrix transpose = DoubleMatrix(this->mColumns, this->mRows);
    forEachRowNColumn([&transpose](const int r, const int c, const double value)
    {
        transpose.set(c, r, value);
    });
    return transpose;
}   

void DoubleMatrix::print() const
{
    for (int i = 0; i < mRows; ++i)
    {
        for (int j = 0; j < mColumns; ++j)
        {
            std::cout << this->get(i, j) << "\t";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

void DoubleMatrix::forEachRowNColumn(const matrixElem& block) const
{
    int r = 0;
    int c = 0;
    while (r < mRows)
    {
        while (c < mColumns)
        {
            block(r, c, mMatrixData[r][c]);
            c++;
        }
        r++;
        c = 0;
    }
}

On my constructor I initialize the double** with zeros.

But the problem is on the methods that has to return a new DoubleMatrix instance like transpose(). When I assigned a variable to this method return, the data is "unable to read memory". Like this, for example:

#include <iostream>
#include "DoubleMatrix.h"

int main()
{
    DoubleMatrix b = DoubleMatrix(2, 1);
    b.set(0, 0, 1);
    b.set(1, 0, 10);
    std::cout << "\nMatrix B\n";
    b.print();
    std::cout << "\nMatrix B transposed\n";
    DoubleMatrix c = b.transpose();
    c.print(); // ERROR

    std::cin.get();
    return 0;
}

This is the error presented when the main is called. The error dialog when I run main() function.

If I click break and try to access the data of the matrix, the Locals windows show me the message "": "<Unable to read memory>"

I made this way based on this question too, where is recommended pass the return value by value, exactly I'm doing on transpose() method.

Why this is not working?

PS: I accept recommendations for enhance this code, this is my first project with OO C++, this code is a C++ version of my kotlin library GitHub link.

Vinicius Almada
  • 386
  • 3
  • 13
  • 2
    As per "why this should answer your question", you call *copy constructor* in your `transpose()` method where you `return` the object. Default copy constructor is not correct in this case (as strongly suggested by the Rule of Three). Also, your class is leaking almost all of the memory allocated. You need one `delete[]` for each `new[]` and you have one `new[]` + `new[]` in `for` loop but only single `delete[]` in destructor. – Yksisarvinen Jan 04 '20 at 17:15
  • 1
    You should invest I'd say a year or so spending quality time with a good C++ book, learning the fundamental principles of memory management and OOP, like Rule Of 3. This is something that can't really be figured out by trial and error, like this. – Sam Varshavchik Jan 04 '20 at 17:40
  • `0xFEEEFEEE` is a magic debugging code. [https://stackoverflow.com/a/127404/487892](https://stackoverflow.com/a/127404/487892) – drescherjm Jan 04 '20 at 17:41

0 Answers0