我上了这堂课:
int x;
int y;
int **mat;
MyMatrix::MyMatrix(int a, int b)
:x(a), y(b)
{
int i ,j;
mat = new int*[x];
for (int i = 0; i < x; ++i)
mat[i] = new int[y];
for (i = 0; i < x; ++i){
for (j = 0; j < y; ++j){
mat[i][j] = i + j;
}
}
}
MyMatrix& MyMatrix::add(MyMatrix m){
int i, j;
if (x != m.x || y != m.y) return *this;
for (i = 0; i < x; ++i){
for (j = 0; j < y; ++j){
mat[i][j] += m.mat[i][j];
}
}
return *this;
}
MyMatrix::~MyMatrix()
{
for (int i = 0; i < x; ++i)
delete[] mat[i];
delete mat;
}
这是我的主要内容:
int main(){
MyMatrix m(2, 3);
MyMatrix m1(2, 3);
m.add(m1);
m.print();
}
一切正常,并给我打印正确的答案,但有一些分配问题。 我正在使用调试器,并且在第二次程序崩溃时看到该程序对析构函数进行了两次。
请解释我的问题是什么?为什么?
答案 0 :(得分:2)
是的,当您调用m.add
时,参数按值传递,因此在方法的条目处构建新矩阵,然后在结束时销毁。要消除此效果,请使用by-ref传递:
MyMatrix& MyMatrix::add(const MyMatrix &m){
...
}
这样原始的一个传递给函数,但const
阻止你在方法执行期间修改它。
答案 1 :(得分:1)
我看到的最明显的事情是,在你的析构函数中,你需要在垫子上使用delete []
。另一个问题是你需要提供一个拷贝构造函数。我相信this answer是最大的问题。当您传递值并复制MyMatrix
时,默认的复制构造函数只会复制所有成员变量:x
,y
和mat
。这会生成mat
指针的副本,而不是它指向的数据。当该临时MyMatrix
被销毁时,将删除m1
中分配的数据,因为临时mat
指向它。因此,当您的程序试图销毁m1
时,它会删除一个已被删除的指针并导致崩溃。
复制构造函数如下所示:
MyMatrix::MyMatrix(const MyMatrix& other) : x(other.x), y(other.y)
{
mat = new int*[x];
for (int i = 0; i < x; ++i)
mat[i] = new int[y];
for (int i = 0; i < x; ++i){
for (int j = 0; j < y; ++j){
mat[i][j] = other.mat[i][j];
}
}
}
其他一些提示。您可能希望使用operator+=
而不是add
函数,以便编写如下代码:
m += m1;
只需将MyMatrix& MyMatrix::add(MyMatrix m)
更改为MyMatrix& MyMatrix::operator+=(const MyMatrix &m)
即可。此外,您的内存分配效率相对较低。它可以工作,但有更好的方法来实现2D矩阵。如果这是一个学习练习,这很好。如果您真的想在C ++中使用矩阵,我建议您查看像OpenCV这样的库。