0

我正在尝试在二维矩阵中进行一些操作。我重载了 (+ , - 和 *) 来进行计算。我有一个关于(我相信)内存管理的问题。看下面的代码:

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;
}

我想我的问题在这里:

Mtx S(nrows, ncols, ETS); 
delete [] ETS;
return S;

这是返回的正确方法ETS吗?还是您认为问题出在构造函数上?当我执行上述返回时,我没有得到任何输出!

这是构造函数Mtx S(nrows, ncols, ETS);

Mtx::Mtx(int rows, int cols, double **ETS)
{
ets = new double*[nrows];
for (int i = 0; i < nrows; i++) {
    ets[i] = new double[ncols];
}
for (int i = 0; i < nrows; i++) {
    for (int j = 0; j < ncols; j++) {
        ets[i][j] = ETS[i][j];
    }
  }
} 

我的复制构造函数:

Mtx::Mtx(const Mtx& rhs)
:nrows(rhs.nrows), ncols(rhs.ncols)
    {
ets = new double*[nrows];
for (int i = 0; i < nrows; i++) {
    ets[i] = new double[ncols];
}

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

我超载<<打印M3。它工作正常,因为我测试了打印M1M2.

我也做了以下,但仍然没有工作:

Mtx S(nrows, ncols, ETS);
for (int i = 0; i < rhs.nrows; i++) {
    delete [] ETS[i];
}
delete [] ETS;
return S;
}
4

3 回答 3

3

你可以改为使用

std::vector< std::vector<double> > 

代替

double ** 

就界限而言,这将更加安全。你只需要使用函数

std::vector::size() 

std::vector::clear() 

在析构函数中。:)

于 2012-07-22T05:07:57.683 回答
2

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

// 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;
}
于 2012-07-22T05:05:07.073 回答
2

是的,你指出的地方有问题。您必须删除 ETS 中指针中指向的所有内存。所以,它应该更像:

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

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

于 2012-07-22T03:43:06.117 回答