我正在学习c ++并使用我的代码生成Class的操作。
但是,当我尝试删除整个工作后用户输入的两个矩阵时,会弹出消息:
“Matrix 1.3.exe中的0x0F4DBF9B(ucrtbased.dll)抛出异常:0xC0000005:访问冲突读取位置0xDDDDDDCD”
at“(45)delete [] arr [i];” line,在析构函数中。
我尝试删除括号,但由于我需要这些括号来删除数组,所以它也无效。
你知道这里出了什么问题吗?
#include <iostream>
#include <iomanip>
using namespace std;
class Matrix
{
private:
int row, col;
int** arr;
public:
Matrix(int, int);
~Matrix();
int getRow() const;
int getCol() const;
int** getMatrixArr() const;
friend Matrix* operator+(const Matrix&, const Matrix&);
friend Matrix* operator-(const Matrix&, const Matrix&);
friend Matrix* operator*(const Matrix&, const Matrix&);
friend Matrix* operator*(const Matrix&, int);
friend ostream& operator<<(ostream&, const Matrix*);
friend istream& operator>>(istream&, const Matrix&);
};
//construct and destruct--------------------------------------------------------------------------------------------------
Matrix::Matrix(int row, int col)
{
this->row = row;
this->col = col;
arr = new int*[row];
for (int i = 0; i < row; i++)
{
arr[i] = new int[col];
}
}
Matrix::~Matrix()
{
for (int i = 0; i < row; i++)
{
delete[] arr[i];
}
delete[] arr;
}
//getters------------------------------------------------------------------------------------------------------------------
int Matrix::getRow() const
{
return row;
}
int Matrix::getCol() const
{
return col;
}
int** Matrix::getMatrixArr() const
{
return arr;
}
//operation methods(OpOv)----------------------------------------------------------------------------------------------------------
Matrix* operator+(const Matrix& m, const Matrix& n)
{
Matrix* sum = new Matrix(m.row, m.col);
cout << "calculating..." << endl;
for (int i = 0; i <m.row; i++)
{
for (int j = 0; j <m.col; j++)
{
cout << setw(3) << m.arr[i][j] << "+" << n.arr[i][j];
sum->arr[i][j] = m.arr[i][j] + n.arr[i][j];
}
cout << endl;
}
return sum;
}
Matrix* operator-(const Matrix& m, const Matrix& n)
{
Matrix* sum = new Matrix(m.row, m.col);
cout << "caluclating..." << endl;
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < m.col; j++)
{
cout << setw(3) << m.arr[i][j] << "-" << n.arr[i][j];
sum->arr[i][j] = m.arr[i][j] - n.arr[i][j];
}
cout << endl;
}
return sum;
}
Matrix* operator*(const Matrix& m, const Matrix& n)
{
Matrix* sum = new Matrix(m.row, n.col);
cout << "calculating..." << endl;
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < n.col; j++)
{
sum->arr[i][j] = 0;
}
}
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < n.col; j++)
{
for (int t = 0; t < m.col; t++)
{
cout << setw(3) << "+" << m.arr[i][t] << "x" << n.arr[t][j];
sum->arr[i][j] += m.arr[i][t] * n.arr[t][j];
}
}
cout << endl;
}
return sum;
}
Matrix* operator*(const Matrix& m, int num)
{
Matrix* sum = new Matrix(m.row, m.col);
cout << "calculating..." << endl;
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < m.col; j++)
{
cout << setw(3) << m.arr[i][j] << "x" << num;
sum->arr[i][j] = m.arr[i][j] * num;
}
cout << endl;
}
return sum;
}
// input & output ---------------------------------------------------------------------------------------------------------------------
istream& operator>>(istream& is, const Matrix& m)
{
cout << "Enter the values for the Matrix (expecting: " << m.row * m.col << "): ";
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < m.col; j++)
{
is >> m.arr[i][j];
}
}
return is;
}
ostream& operator<<(ostream& os, const Matrix* m)
{
cout << "result: " << endl;
for (int i = 0; i < m->row; i++)
{
for (int j = 0; j < m->col; j++)
{
os << setw(3) << m->arr[i][j];
}
cout << endl;
}
return os;
}
//main-------------------------------------------------------------------------------------------------------------------------------------
int main()
{
int rowNum1, colNum1;
cout << "what is the row of the Matrix 1?: " << endl;
cin >> rowNum1;
cout << "What is the column for the Matrix 1?: " << endl;
cin >> colNum1;
Matrix m1(rowNum1, colNum1);
cin >> m1;
int rowNum2, colNum2;
cout << "what is the row of the Matrix 2?: " << endl;
cin >> rowNum2;
cout << "What is the column for the Matrix 2?: " << endl;
cin >> colNum2;
Matrix m2(rowNum2, colNum2);
cin >> m2;
int choice;
do
{
cout << "Now, what operation do you want to use?" << endl;
cout << "1) addition, 2) Sub action, 3)Multiplication, 4) scalar multiplication 5) quit" << endl << ":";
cin >> choice;
if (choice == 1)
{
if (m1.getRow() != m2.getRow() || m1.getCol() != m2.getCol())
{
cout << "The number of rows or columns of both Matrices are not same, you cannot add them together." << endl;
return 0;
}
else
{
Matrix * result = (m1 + m2);
cout << result << endl;
}
}
else if (choice == 2)
{
if (m1.getRow() != m2.getRow() || m1.getCol() != m2.getCol())
{
cout << "The number of rows or columns of both Matrices are not same, you cannot add them together." << endl;
return 0;
}
else
{
Matrix * result = (m1 - m2);
cout << result << endl;
}
}
else if (choice == 3)
{
if (m1.getCol() != m2.getRow())
{
cout << "Your first Matrix's number of columns and the second Matrice's number of rows are not accorded." << endl;
return 0;
}
else
{
Matrix* result = (m1 * m2);
cout << result << endl;
}
}
else if (choice == 4)
{
int value;
cout << "What is the integer value for the multiplication?: ";
cin >> value;
int MatCho;
cout << "First Matrix or Second Matrix(1 or 2)?: ";
cin >> MatCho;
if (MatCho == 1)
{
Matrix* result = (m1 * value);
cout << result << endl;
}
else if (MatCho == 2)
{
Matrix* result = (m2 * value);
cout << result << endl;
}
else
{
cout << "invalid input" << endl;
}
}
else if (choice == 5)
{
break;
}
else
{
cout << "Invalid input" << endl;
}
} while (choice != 5);
m1.~Matrix();
m2.~Matrix();
return 0;
}
答案 0 :(得分:1)
这里有两个问题:
永远不要像在这里使用m1和m2那样明确地调用析构函数。无论如何,它们的析构函数将在主函数结束时自动调用。所以对你来说,析构函数会运行两次。在第二次运行时,指针数组已被删除。但是row,col和指针仍然具有旧值,并将尝试访问和删除已释放的内存。
您对矩阵执行的所有操作都会泄漏内存。您在操作员函数内部使用new,但从不删除结果。期望函数用户删除已分配的内存是一个坏习惯。按价值返回。如果您实现移动构造函数(http://www.learncpp.com/cpp-tutorial/15-3-move-constructors-and-move-assignment/)
答案 1 :(得分:0)
删除对析构函数的手动调用。当它们被堆栈分配时,你使用的C ++编译器会在你退出main函数时处理它们,即使你已经调用它们(这就是正在发生的事情)。