为什么调用赋值运算符会触发销毁函数
why calling assignment operator triggers destruction function?
我有一个名为矩阵的类,带有二维指针布尔**矩阵。
看看这个代码:
void Matrix::operator=(const Matrix& A){
cout << "address in A : " << A.matrix << endl ;
cout << "address in y : " << matrix << endl ;
//return *this;
}
我在主函数中调用了我的 = 运算符,如下所示:
Matrix x(3,5);
Matrix y(3,5);
x.set(1,4,1);
cout << "address out X: " << x.matrix << endl;
cout << "address out Y: " << y.matrix << endl;
y = x;
cout << "address out X: " << x.matrix << endl;
cout << "address out Y: " << y.matrix << endl;
解构器是这样的:
Matrix::~Matrix(){
cout << "address de : " << matrix <<endl;
for (int i=0;i<m;i++)
delete[] matrix[i];
delete[] matrix;
cout << "address de finish : " << matrix <<endl;
}
当我在 xcode 中运行我的程序时,我得到:
address out X: 0x100103ab0
address out Y: 0x100103af0
address in A : 0x100103ab0
address in y : 0x100103af0
address out X: 0x100103ab0
address out Y: 0x100103af0
address de : 0x100103af0
address de finish : 0x100103af0
address de : 0x100103ab0
address de finish : 0x100103ab0
它看起来不错,但是当我像这样更改 = 运算符函数时:
Matrix Matrix::operator=(const Matrix& A){
cout << "address in A : " << A.matrix << endl ;
cout << "address in y : " << matrix << endl ;
return *this;
}
我得到这个结果:
address out X: 0x100103ab0
address out Y: 0x100103af0
address in A : 0x100103ab0
address in y : 0x100103af0
address de : 0x100103af0
address de finish : 0x100103af0
address out X: 0x100103ab0
address out Y: 0x100103af0
address de : 0x100103af0
Thesis(26190) malloc: *** error for object 0x100103b10: pointer being freed was not allocated
谁能向我解释为什么析构函数在后一段代码中更快地触发?! 以及我该如何防止它
提前谢谢你
原因是修改后的复制赋值运算符按值返回,该值创建矩阵的副本,返回它,然后销毁它。
复制赋值运算符的规范签名将是Matrix& Matrix::operator=(const Matrix& A)
(请注意,我是通过非常量引用返回的(。
编辑:请记住,如果您只使用vector
所有这些内存管理就会消失,所有这些函数都可以使用编译器默认值。尽管如果您实际上将bool
存储在矩阵中,vector<bool>
是专用的,您应该确保了解该专用化如何与您的代码交互。
赋值运算符按值返回*this
,并复制它。通常,您会返回一个引用:
Matrix& Matrix::operator=(const Matrix& A)
// ^
复制是使用隐式复制构造函数创建的,该构造函数只是复制成员指针。您现在有两个对象,它们都认为它们"拥有"分配的内存。operator=
返回的临时值很快就会被销毁,删除内存,并留下y
一个悬而未决的指针;当您尝试再次删除相同的内存时,y
会收到错误。
这就是为什么管理资源的类应该遵循三法则,以确保它们可以安全地复制。 标准容器(如std::vector
执行此操作;通常最好使用这些容器,而不是自己管理内存。
相关文章:
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 类型擦除的std::function与虚拟函数调用的开销