我对C++还是个新手。我的问题是编写一个关于矩阵的OOP C++程序(创建一个矩阵类并向这个类添加一些方法)以下是我的代码:
#include <iostream>
#include <iomanip>
using namespace std;
class Matrix
{
private:
int col, row;
double *a;
public:
Matrix(int col = 1, int row = 1) {
this->col = col; this->row = row;
}
~Matrix() {
delete a;
col = row = 0;
}
void insertMatrix() {
a = new double[this->col * this->row];
for (int i = 0; i < this->row; i++)
for (int j = 0; j < this->col; j++) {
cout << endl << "a[" << i + 1 << "][" << j + 1 << "] = ";
cin >> this->a[i * this->col + j];
}
}
void printMatrix() {
for (int i = 0; i < this->row; i++) {
for (int j = 0; j < this->col; j++)
cout << setw(9) << this->a[i * this->col + j];
cout << endl;
}
cout << endl;
}
int getCol() {
return col;
}
int getRow() {
return row;
}
Matrix operator+(Matrix);
Matrix operator-(Matrix);
};
Matrix Matrix::operator+(Matrix x) {
if (x.col != col || x.row != row) {
cout << endl << "Can't add these two matrices";
exit(0);
}
Matrix sum(x.col, x.row);
sum.a = new double(sum.col * sum.row);
for (int i = 0; i < this->col * this->row; i++)
sum.a[i] = a[i] + x.a[i];
return sum;
}
Matrix Matrix::operator-(Matrix x) {
if (x.col != this->col || x.row != this->row) {
cout << endl << "Can't subtract these two matrices";
exit(0);
}
Matrix dif(this->col, this->row);
dif.a = new double(dif.col * dif.row);
for (int i = 0; i < this->col * this->row; i++)
dif.a[i] = this->a[i] - x.a[i];
return dif;
}
int main()
{
int row, col;
cout << endl << "Column = "; cin >> col; cout << endl << "Row = "; cin >> row;
Matrix A(col, row), B(col, row);
A.insertMatrix(); B.insertMatrix();
cout << "Matrix A: " << endl; A.printMatrix();
cout << "Matrix B: " << endl; B.printMatrix();
cout << "Matrix (A + B)" << endl; (A + B).printMatrix();
cout << "Matrix (A - B)" << endl; (A - B).printMatrix();
}我看不出有任何错误。我可以编译这个程序。但每次我尝试输入一些数字时,程序总是冻结,并显示“停止工作”的消息,并得到错误的答案。我在Windows8中使用的是Orwell Dev C++,有人能解释一下原因吗?
发布于 2015-01-05 03:55:19
一个错误是您错误地使用了new。
sum.a = new double(sum.col * sum.row);上面的代码动态创建了一个单精度的双精度值,并将该值初始化为sum.col * sum.row。
您应该使用new[]
sum.a = new double[sum.col * sum.row];那么在使用new[]时,您必须使用delete[],而不是delete。
另一个错误是您没有在构造函数中初始化a指针。当矩阵被销毁时,析构函数将在指向谁知道在哪里的指针上发出一个delete。
因此,这个简单的一行程序有问题:
int main() {
Matrix m;
} // < -- problems here 修复方法是确保您的指针已初始化:
Matrix(int mcol = 1, int mrow = 1) : a(0), col(mcol), row(mrow) {}请注意,a现在已初始化为0。还要注意成员初始化列表的用法。
然而,另一个错误是您的Matrix类缺少用户定义的复制构造函数和赋值操作符。当您通过值返回或传递Matrix时,就像这里所做的那样:
Matrix Matrix::operator+(Matrix x)拷贝只会在指针上做一次浅拷贝,因此你的程序会有内存泄漏,双重释放错误等。请阅读“规则3":
其他问题:
不要在类代码中调用 exit(0) 。如果我想使用你的Matrix类,并且我给operator +一个不正确大小的Matrix,请不要关闭我的应用程序!相反,抛出一个异常,或者发出一个assert()。
查看此处:exit() call inside a function which should return a reference
发布于 2015-01-05 03:59:22
程序中的主要问题是,在重载的运算符中,返回一个堆栈分配的Matrix对象,该对象将调用复制构造函数。
但是由于您没有定义,编译器将为您生成它,执行逐位复制,这意味着复制的对象中的d指针将指向与堆栈中的对象相同的位置。
因此,析构函数被调用两次。
当离开函数overloads;
(A + B).printMatrix();
这就是为什么你的程序会异常终止,出现类似下面这样的错误:
错误在`./rez':():无效的下一个大小(快速):0x00000000020390c0
正如其他人所建议的那样,如果您遵循3 (或C++11/14中的5)的规则,您就不会遇到这个问题。
发布于 2015-01-05 03:57:00
另一个错误是对规则3的公然违反;复制您的Matrix会破坏它的所有权语义。
为什么不使用std::vector<double>来代替呢?
https://stackoverflow.com/questions/27769607
复制相似问题