I want to dinamically alocate memory for the matrix, in the constructor.I want mData
to be a pointer to double
values.
getvalue() setValue()
the getter should return the value at row_x and column_x, and the setter should set the value at row_x and column_x, but getter and setter doesn't seem to work;
operator
have to check for 2 same sized matrix, and summing element by element.
Operator *
also needs to check for 2 same sized matrix, and multiply element by element.
Operator ^
needs to check if it is possible to multiply row by column 2 matrix, and then do that.
Here is my code:
class Mat{
private:
uint16_t mRows;
uint16_t mCols;
double * mData;
public:
Mat(uint16_t r, uint16_t c){
mRows = r;
mCols = c;
mData = new double[mRows * mCols];
}
Mat(uint16_t c){
mCols = c;
mRows = 1;
mData = new double [mCols];
}
Mat(){
mRows = 0;
mCols = 0;
}
Mat(const Mat &mat) : mRows(mat.mRows), mCols(mat.mCols), mData(mat.mData){
}
double getValue(uint16_t r, uint16_t c){
double val = mData [r*c c];
return val;
}
void setValue(uint16_t r, uint16_t c,double value){
mData[r*c c] = value;
}
~Mat(){
}
Mat operator (const Mat &mat){
Mat result;
int ok=0;
if(mat.mRows == mRows && mat.mCols == mCols){
ok=1;
result.mData[mRows*mCols ] = mData[mRows*mCols ] mat.mData[mat.mRows*mat.mCols];
}
if(ok == 0)
return result.mData[0];
else
return result;
}
Mat operator * (const Mat &mat){
Mat result;
int ok=0;
if(mat.mRows == mRows && mat.mCols == mCols){
ok=1;
result.mData[mRows*mCols] = mData[mRows*mCols] * mat.mData[mat.mRows*mat.mCols];
}
if(ok == 0)
return result.mData[0];
else
return result.mData[mRows*mCols];
}
Mat operator ^ (const Mat &mat){
Mat result;
int ok=0;
if(mat.mRows == mCols && mat.mCols == mRows){
ok=1;
result.mData[mRows] = mData[mRows] * mat.mData[mat.mCols];
}
if(ok == 0)
return result.mData[0];
else
return result.mData[mRows];
}
};
I want to continue with this idea, but i am not sure what i am missing
CodePudding user response:
Using std::vector<double>
instead of double*
makes the memory management and copying significant easier and less error prone.
I've also noticed an error in element wise access, where one should use r*mCols c
instead of r*c c
. To solve the problem with element wise matrix operations, you need to walk over all elements:
for (size_t r = 0; r < mRows; r)
for (size_t c = 0; c < mCols; c)
result[r*mCols c] = src1[r*mCols c] src2[r*mCols c]
Here is an example implementation of Mat. I've only done operator
so far, but should easily extend to the other operators:
class Mat
{
private:
size_t mRows;
size_t mCols;
std::vector<double> mData;
public:
// constructors
Mat(size_t rows, size_t cols, double v = 0.0f)
: mRows(rows), mCols(cols), mData(mRows*mCols, v)
{}
Mat(size_t cols, double v = 0.0f)
: mRows(1), mCols(cols), mData(mRows*mCols,v)
{}
Mat()
: mRows(0), mCols(0), mData()
{}
// automatic copy & move construction just works^TM using std::vector
Mat(const Mat&) = default;
Mat(Mat&&) = default;
// same with automatic copy & move assignment
Mat& operator= (const Mat&) = default;
Mat& operator= (Mat&&) = default;
// element access
double getValue(size_t r, size_t c) const
{
return mData[r*mCols c];
}
void setValue(size_t r, size_t c, double value)
{
mData[r*mCols c] = value;
}
// element access through operator():
// Mat m(3,3); m(1,2)=5.0f;
double& operator()(size_t r, size_t c)
{
return mData[r*mCols c];
}
const double& operator()(size_t r, size_t c) const
{
return mData[r*mCols c];
}
// in place addition saves unnecessary memory allocation & copying
Mat& operator = (const Mat& m)
{
if (m.mRows != mRows || m.mCols != mCols)
throw std::runtime_error("Mat: dimensions don't match");
// since all matrix elements are contiguous in memory, we can simply to a single for loop
for (size_t i = 0; i < mData.size(); i)
mData[i] = m.mData[i];
return *this;
}
Mat operator (const Mat& m) const
{
if (m.mRows != mRows || m.mCols != mCols)
throw std::runtime_error("Mat: dimensions don't match");
// copy this Mat into a new Mat
Mat result(*this);
// add m to result in place and return result
result = m;
return result;
}
};
CodePudding user response:
Your memory management is broken.
In your copy constructor, you have to copy the contents of mData
, not just the pointer. So you need to allocate a new buffer and copy the input data to that.
Your destructor needs to delete mData
, you are leaking memory.
In your operators, you can't use a default constructed matrix as the target. You have to create your target with the correct dimensions or it doesn't have a buffer allocated!
The return values of your operators are illegal. You must always return the type specified in the signature. You must not return result.mData[0]
, not even in the error case! You can either return a default constructed Mat
or throw
an exception in such case.