删除动态分配的二维数组时发生错误?
Posted
技术标签:
【中文标题】删除动态分配的二维数组时发生错误?【英文标题】:Error happens during deleting the dynamic allocated 2d array? 【发布时间】:2018-02-08 04:25:41 【问题描述】:我正在学习 c++,并制作了带有操作的矩阵生成类的代码。
但是,当我尝试在整个工作后删除用户输入的两个矩阵时,它会弹出消息:
“在 Matrix 1.3.exe 中的 0x0F4DBF9B (ucrtbased.dll) 处引发异常:0xC0000005:访问冲突读取位置 0xDDDDDDCD”
在“(45)delete[] arr[i];”行,在析构函数中。
我试图删除括号,但由于我需要这些括号来删除数组,它也不起作用。
你知道这里出了什么问题吗?
#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;
【问题讨论】:
你为什么不直接调用delete m1; delete m2
,你还需要在析构函数中使用delete[] arr;
,因为你已经在循环逐行销毁了。
@macroland:你不能删除 m1; m1 是堆栈上的对象,而不是指向动态内存的指针。还有 delete[] arr;是必需的,指向每个矩阵行的指针数组也需要删除。
@Morgan:是的,刚刚意识到他们在堆栈上。
【参考方案1】:
这里有两个问题:
永远不要像在此处使用 m1 和 m2 那样显式调用析构函数。在任何情况下,它们的析构函数都会在主函数结束时自动调用。所以对你来说,析构函数将运行两次。在第二次运行时,指针数组已被删除。但是 row、col 和指针仍然有它们的旧值,并且会尝试访问和删除已经释放的内存。
您对矩阵执行的所有操作都会泄漏内存。您在运算符函数中使用 new 但从不删除结果。期望函数的用户删除您分配的内存是一个坏习惯。而是按值返回。如果您实现移动构造函数,这实际上不会推断出任何性能损失 (http://www.learncpp.com/cpp-tutorial/15-3-move-constructors-and-move-assignment/)
【讨论】:
【参考方案2】:删除对析构函数的手动调用。由于它们是堆栈分配的,因此您使用的 C++ 编译器将在您退出主函数时处理它们,即使您已经调用了它们(正在发生的事情)。
【讨论】:
以上是关于删除动态分配的二维数组时发生错误?的主要内容,如果未能解决你的问题,请参考以下文章