删除动态分配的2d数组时发生错误?

时间:2018-02-08 04:25:41

标签: c++ arrays matrix dynamic

我正在学习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;
}

2 个答案:

答案 0 :(得分:1)

这里有两个问题:

  1. 永远不要像在这里使用m1和m2那样明确地调用析构函数。无论如何,它们的析构函数将在主函数结束时自动调用。所以对你来说,析构函数会运行两次。在第二次运行时,指针数组已被删除。但是row,col和指针仍然具有旧值,并将尝试访问和删除已释放的内存。

  2. 您对矩阵执行的所有操作都会泄漏内存。您在操作员函数内部使用new,但从不删除结果。期望函数用户删除已分配的内存是一个坏习惯。按价值返回。如果您实现移动构造函数(http://www.learncpp.com/cpp-tutorial/15-3-move-constructors-and-move-assignment/

  3. ,这实际上不会推断任何性能损失

答案 1 :(得分:0)

删除对析构函数的手动调用。当它们被堆栈分配时,你使用的C ++编译器会在你退出main函数时处理它们,即使你已经调用它们(这就是正在发生的事情)。