程序按执行方式工作,直到我向其添加析构函数为止
program works as excpected untill I add a destructor to it
#include <iostream>
using namespace std;
class Matrix {
public:
long int **Matr;
long int n;
void Create() {
Matr = new long int *[n];
for (int z = 0; z < n; z++)
Matr[z] = new long int[n];
}
// constructors and destructor
Matrix() : n(5) { Create(); }
Matrix(long int i) : n(i) { Create(); }
// Copy constructor
Matrix(Matrix &N) {
n = N.n;
Matr = new long int *[n];
for (int i = 0; i < n; i++)
Matr[i] = new long int[n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Matr[i][j] = N.Matr[i][j];
}
}
}
Matrix operator*(Matrix &mx) {
int i, j, k, num;
Matrix result(n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
num = 0;
for (int k = 0; k < n; k++) {
num += Matr[i][k] * mx.Matr[k][j];
}
result.Matr[i][j] = num;
return result;
}
~Matrix() {
for (int z = 0; z < n; z++) {
delete[] Matr[z];
}
delete[] Matr;
}
void Display() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << Matr[i][j];
}
cout << endl;
}
}
Matrix operator+(Matrix &mx) {
Matrix result(n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
result.Matr[i][j] = Matr[i][j] + mx.Matr[i][j];
// cout << result.Matr[i][j] << "n";
}
}
return result;
}
};
int main() {
Matrix M(2);
M.Matr[0][0] = 0;
M.Matr[0][1] = 1;
M.Matr[1][0] = 2;
M.Matr[1][1] = 3;
Matrix N(2);
N.Matr[0][0] = 0;
N.Matr[0][1] = 1;
N.Matr[1][0] = 2;
N.Matr[1][1] = 3;
Matrix C;
C = M + N;
cout << C.Matr[0][0];
return 0;
}
我正在用一些基本方法做一个矩阵 OOP 类。我不能按照我想要的方式做"+"运算符工作。在这种情况下,当我尝试打印 C.Matr[0][0] 时,出于某种原因它正在打印随机数,但如果我只是从代码中删除析构函数,它会按预期工作并打印 0。有人可以帮助我弄清楚为什么会发生这种情况吗?多谢。
C
被分配了一个具有共享Matr
的临时 。临时指针会立即死亡,您会删除 dtor 中的悬空指针。
三/五/零规则将帮助您防止它。
您缺少复制赋值运算符的内容:
Matrix& operator=(const Matrix& N)
{
// copy to temporary matrix
long int tmpN = N.n;
long int** tmpMatr = new long int*[tmpN];
for (int i = 0; i < tmpN; i++)
tmpMatr[i] = new long int[tmpN];
for (int i = 0; i < tmpN; i++)
{
for (int j = 0; j < tmpN; j++)
tmpMatr[i][j] = N.Matr[i][j];
}
// swap
long int** swapMatr = Matr;
long int swapN = n;
Matr = tmpMatr;
n = N.n;
// deallocate old Matr
for (int z = 0; z<swapN; z++){
delete[] swapMatr[z];
}
delete[] swapMatr;
return *this;
}
在线 gdb
必须实现赋值运算符,而不仅仅是复制构造函数和析构函数。
实现赋值运算符的最简单方法是使用复制/交换习惯用法:
#include <algorithm>
//...
class Matrix
{
//...
int **Matr;
int n;
//...
public:
Matrix& operator=(const Matrix& m)
{
if ( this != &m )
{
Matrix temp(m); // create a copy of the passed in value
std::swap(temp.Matr, Matr); // swap out the internals with *this
std::swap(temp.n, n);
} // Here temp's destructor removes the old memory that *this
// previously had
return *this;
}
//...
};
请注意,这仅在您有一个有效的、没有错误的复制构造函数和析构函数时才有效。
此外,您的复制构造函数应该采用const
引用,而不仅仅是对Matrix
的引用:
Matrix(const Matrix& m) { ... }
进行这些更改后,程序将不再崩溃,如下所示。
您没有赋值运算符,所以谁知道C = M + N;
行在做什么?
好吧,它使用默认的赋值运算符,它只是依次复制每个成员。特别是,指针Matr
是从临时M+N
中的指针复制的,因此它指向分配给临时的内存,然后被销毁。
在添加析构函数之前,您遇到了内存泄漏,因此值保留在堆中,并且它似乎有效。添加释放内存的析构函数后,它显然很快被覆盖。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 在 UML 类图中为C++类添加构造函数和析构函数
- 添加自定义析构函数时,Move 构造函数在派生类中消失
- 为什么添加析构函数(甚至是空的)会破坏我的结构,该结构使用 ref 转发和折叠来保存 ref 或值的副本?
- 程序按执行方式工作,直到我向其添加析构函数为止
- 添加虚拟析构函数会使代码大小膨胀
- 创建/向容器添加对象时如何使用构造函数/析构函数
- 为什么虚拟类的析构函数不会自动添加到 vtable 中?
- 添加析构函数后,在程序调用它之前,我就出现了错误
- 如何正确地将对象添加到向量,而无需两次调用析构函数
- 如何在不调用现有对象的析构函数的情况下在向量中添加和初始化对象
- 为什么我的课'当我向向量添加实例时,会调用s析构函数
- 添加析构函数逻辑会导致分段错误
- 为什么下面的类需要析构函数?如何添加一个
- 添加析构函数定义将创建运行异常
- 为什么当定义析构函数时,编译器不再添加默认的move函数和赋值函数
- 为什么在类中添加析构函数会使类不可移动