双重自由或腐败 - 为什么
Double free or corruption- why?
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;
}
我看到的一个错误是,在您的复制构造函数中,您正在删除从未分配的内存:
this->n=mat.n;
if (wsk!=0) delete []wsk;
检查非 NULL 对您没有帮助。 该指针可能具有非 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
中删除此行。 将自动调用对象的析构函数。
在我看来
,delete[] 试图为数组的每个元素调用析构函数,然后它破坏了指针。它可能会带来双重免费错误。
您是否尝试过更换
int *foo=new int[n*m]
用老C马洛克?
int *foo;
foo=(int*)malloc(n*m*sizeof(int));
这样,您可以使用删除而不是删除[]。我希望这有效。
玩得开心,让我知道
格芯
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么成员函数地址离自由函数这么远?
- 为什么未调用自由函数作为构造函数中的参数传递
- 为什么命名空间内的自由功能模棱两可
- 为什么标准允许我在没有析构函数的情况下自由存储分配类
- 双重自由或腐败 - 为什么
- 为什么类成员函数使用相同名称阴影自由函数
- 为什么我们可以检测 SFINAE 中 operator() 的默认参数值的存在,而不是自由函数和 PMF 的默认参数值
- 为什么 std::bind1st 不适用于自由函数
- 为什么双重自由或腐败
- 为什么在运算符重载中会出现自由错误
- 为什么会出现这种双自由错误
- 为什么泛型编程设计更喜欢自由函数而不是成员函数
- 为什么自由函数指针总是指针类型,而成员函数指针实际上不是指针?
- 为什么字符串上的双自由运算符=
- 这种代码理论上会有双重自由,但为什么没有重复
- 为什么我更喜欢使用自由存储而不是堆
- 为什么编译器不会自动内联自由定义的函数?而是导致链接器错误