C++ C+中的二维矩阵+;

C++ C+中的二维矩阵+;,c++,memory-management,matrix,C++,Memory Management,Matrix,我想在二维矩阵中做一些运算。我重载了(+、-和*)来进行计算。我有一个关于(我相信)内存管理的问题。请看以下代码: Mtx M1(rows1,cols1,1.0); //call the constructor Mtx M2(rows2,cols2,2.0); //call the constructor Mtx M3(rows3,cols3,0.0); //call the constructor M3 = M1 + M2; cout << M3 << endl

我想在二维矩阵中做一些运算。我重载了(+、-和*)来进行计算。我有一个关于(我相信)内存管理的问题。请看以下代码:

Mtx M1(rows1,cols1,1.0); //call the constructor 
Mtx M2(rows2,cols2,2.0); //call the constructor 
Mtx M3(rows3,cols3,0.0); //call the constructor 

M3 = M1 + M2;
cout << M3 << endl;

Mtx Mtx::operator+(const Mtx &rhs)
{

double **ETS;
ETS = new double*[nrows];
for (int i = 0; i < rhs.nrows; i++) {
    ETS[i] = new double[rhs.ncols];
}
if (ETS == NULL) {
    cout << "Error Allocation on the Heap" << endl;
    exit(1);
}

for (int i = 0; i < rhs.nrows; i++) {
    for (int j = 0; j < rhs.ncols; j++) {
        ETS[i][j] = 0.0;
    }
}

for (int i = 0; i < rhs.nrows; i++) {
    for (int j = 0; j < rhs.ncols; j++) {
        ETS[i][j] = ets[i][j];
    }
}


for (int i = 0; i < rhs.nrows; i++) {
    for (int j = 0; j < rhs.ncols; j++) {
        ETS[i][j] = ETS[i][j] + rhs.ets[i][j];
    }
}

Mtx S(nrows, ncols, ETS);
delete [] ETS;
return S;
}
这是返回ETS的正确方法吗?或者你认为问题出在构造器上?我没有得到任何输出,当我做上述返回

这是Mtx S的构造函数(nrows、ncols、ETS)


是的,你指出了一个问题。您必须删除ETS中指针指向的所有内存。因此,它应该更像:

for (int i = 0; i < rhs.nrows; i++) {
    delete [] ETS[i];
}
delete [] ETS;
for(int i=0;i

我的好规则是,每次调用new时,都必须调用delete;您使用
nrows+1
调用new来分配数组,因此必须使用相同的号码删除。这并不难,但当出现问题时,它会提示您。

实现二进制算术运算符的常用方法是将
运算符+=
定义为类成员函数,将
运算符+
定义为独立函数。请注意,
+
运算符是根据
+=
运算符实现的,它通过复制获取其左操作数。只要您的复制构造函数和赋值运算符正确,这应该可以工作

// member function
Mtx& Mtx::operator+=(const Mtx &rhs)
{
    for (int i = 0; i < nrows; ++i) {
        for (int j = 0; j < ncols; ++i) {
            ets[i][j] += rhs.ets[i][j];
        }
    }
    return *this;
}

// non-member function
Mtx operator+(Mtx lhs, const Mtx &rhs)
{
    lhs += rhs;
    return lhs;
}
//成员函数
Mtx和Mtx::运算符+=(常量Mtx和rhs)
{
对于(int i=0;i
您可以使用

std::vector< std::vector<double> > 
就边界而言,这将更加安全。你只需要使用函数

std::vector::size() 


在析构函数中。:)

@Johnsyweb:在链接中,您可以将版本替换为“release”,以始终指向最新版本,即问题可能出在
类Mtx
的复制构造函数中,因为
返回s
需要复制构造。如果不进行深度复制,结果将是错误的。。您似乎已经这样做了。您的复制构造函数泄漏了以前分配给该对象的内存。由于您的类手动管理资源(内存),您应该学习。此外,你应该学习高炉的良好实践是的,我认为你关于赋值运算符的看法是正确的。我以前读过三法则,这不是我第一次使用它。为什么猜测复制构造函数会泄漏内存?你注意到了什么?
for (int i = 0; i < rhs.nrows; i++) {
    delete [] ETS[i];
}
delete [] ETS;
// member function
Mtx& Mtx::operator+=(const Mtx &rhs)
{
    for (int i = 0; i < nrows; ++i) {
        for (int j = 0; j < ncols; ++i) {
            ets[i][j] += rhs.ets[i][j];
        }
    }
    return *this;
}

// non-member function
Mtx operator+(Mtx lhs, const Mtx &rhs)
{
    lhs += rhs;
    return lhs;
}
std::vector< std::vector<double> > 
double ** 
std::vector::size() 
std::vector::clear()