class matrix{
private:
int n, *wsk;
friend istream & operator>>(istream&,matrix&);
friend ostream & operator<<(ostream&,matrix&);
public:
matrix(){
wsk=0;
n=0;
}
matrix(const matrix &mat){
this->n=mat.n;
if (wsk!=0) delete []wsk;
this->wsk=new int [this->n*this->n];
for (int i=0;i<n*n;i++)
wsk[i]=mat.wsk[i];
}
~matrix(){
if (this->wsk!=0) delete[]this->wsk;
}
const matrix & operator=(const matrix &mat){
if(&mat==this) return *this;
if (this->wsk!=0) delete [] this->wsk;
n=mat.n;
this->wsk=new int [n*n];
for (int i=0;i<mat.n*mat.n;i++)
this->wsk[i]=mat.wsk[i];
return *this;
}
};
istream & operator>>(istream &str, matrix& mat){
str >> mat.n;
if (mat.n>0) {
if (mat.wsk != 0) delete[]mat.wsk;
mat.wsk= new int [mat.n*mat.n];
for (int i=0;i<mat.n*mat.n;i++)
str >> mat.wsk[i];
}
return str;
}
ostream & operator<<(ostream &str, matrix& mat){
if (mat.wsk!=0){
for (int i=0;i<mat.n*mat.n;i++){
str << mat.wsk[i] << " ";
if ((i+1)%mat.n==0) str << endl;
}
}
return str;
}
当我试图在main中制作两个矩阵时,第一个维度低于第二个矩阵,正在发生双重自由。当两个矩阵具有相同的维度,或者第一矩阵的维度高于第二矩阵时,没有问题。也许有人可以看到代码并告诉我这是什么问题?
编辑:主要:
int main(){
matrix mac, a, b;
cout << "Put number of dimensions and numbers in matrix ";
cin >> mac;
cout << mac;
cin >> a;
cout << a;
mac.~matrix();
return 0;
}
答案 0 :(得分:2)
我看到的一个错误是,在复制构造函数中,您正在删除从未分配的内存:
this->n=mat.n;
if (wsk!=0) delete []wsk;
检查非NULL对您没有帮助。该指针可能具有非空垃圾值,并且您使用垃圾指针调用delete[]
。只需从复制构造函数中删除该行。
其次,您的赋值运算符存在问题:
const matrix & operator=(const matrix &mat){
if(&mat==this) return *this;
// you've destroyed your data here
if (this->wsk!=0) delete [] this->wsk;
// you've changed one of your members here
n=mat.n;
// what if the line below throws a `std::bad_alloc` exception?
this->wsk=new int [n*n];
评论解释了这个问题。您删除了自己的数据,如果new[]
稍后失败,则无法恢复。
您还会返回const
。对于赋值运算符返回const对象,这是非常规的。
编写赋值运算符的更好方法是:
#include <algorithm>
//...
matrix & operator=(matrix mat)
{
std::swap(n, mat.n);
std::swap(wsk, mat.wsk);
return *this;
}
在给定工作副本构造函数和析构函数的情况下,这可以保证工作。这里使用copy/swap
成语。
此外,在发出delete
或delete[]
时无需检查空指针。所以你的析构函数就是这样:
~matrix(){ delete[]this->wsk; }
编辑:您正在main
函数中执行此操作:
mac.~matrix();
您正在显式调用析构函数。那么当mac
对象超出范围时会发生什么?将自动再次调用析构函数,因此您将获得双删除错误。
从main
删除此行。将自动调用对象的析构函数。
答案 1 :(得分:0)
对我来说,似乎delete []尝试为数组的每个元素调用析构函数,然后它会销毁指针。它可能会导致双重自由错误。
您是否尝试过更换
int *foo=new int[n*m]
旧C malloc?
int *foo;
foo=(int*)malloc(n*m*sizeof(int));
这样你可以使用delete而不是delete []。我希望这有效。
玩得开心,让我知道
GF