我正在尝试在二维矩阵中进行一些操作。我重载了(+, - 和*)来进行计算。关于(我相信)内存管理我有一个问题。请查看以下代码:
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
。它运行正常,因为我测试了打印M1
和M2
。
我也做了以下,仍然没有工作:
Mtx S(nrows, ncols, ETS);
for (int i = 0; i < rhs.nrows; i++) {
delete [] ETS[i];
}
delete [] ETS;
return S;
}
答案 0 :(得分:3)
您可以改为使用
std::vector< std::vector<double> >
而不是
double **
就边界而言,这将更安全。而你只需要使用函数
std::vector::size()
和
std::vector::clear()
在析构函数中。 :)
答案 1 :(得分:2)
是的,你指出了一个问题。您必须删除ETS中指针中指向的所有内存。所以,它应该更像是:
for (int i = 0; i < rhs.nrows; i++) {
delete [] ETS[i];
}
delete [] ETS;
我很好的规则是每次调用new都要调用delete;您使用nrows+1
调用将数组分配给new,因此您必须使用相同的数字进行删除。这并不是一件容易的事情,但是当出现问题时,它会让你知道。
答案 2 :(得分:2)
实现二进制算术运算符的常用方法是将operator+=
定义为类成员函数,将operator+
定义为独立函数。请注意,+
运算符是根据+=
运算符实现的,它的左操作数 通过副本 。只要你的复制构造函数和赋值运算符是正确的,这应该可行。
// 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;
}