Matrix Class Error: Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

Matrix Class Error: Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

第一次使用Whosebug,很高兴认识大家。 我正在写一个矩阵 class 来重载赋值、加法、减法等。 赋值运算符“=”重载部分似乎工作正常,但如果我试图重载加法运算符“+”,我会收到如下错误消息:

“调试断言失败! 程序:...nts\C++\week6....\week6matrix.exe

文件:f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp

第 52 行

表达式:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)"

但是如果我在我的析构函数中删除 "delete[]matrix",一切似乎都有效,但是由于这个项目的要求,我需要在我的析构函数中包含这个术语。

我本来可以张贴图片的,但这是我第一次使用这个网站,所以我还没有这样做的声誉,所以如果我的问题似乎没有意义,我深表歉意,但我会的如果您对我的问题有任何疑问,请尽力解释。

谢谢。

#include<iostream>
#include <stdlib.h>
using namespace std;
//dynamic matrix
class dymatrix
{
  friend ostream & operator << (ostream &os, dymatrix &om);
  friend istream & operator >> (istream &is, dymatrix &om);
private:
  int rows;
  int columns;
  double *matrix;
public:

  dymatrix(){cout<<"Default constructor called"<<endl; columns = 0; rows=0; matrix=0;}
  dymatrix(int inrows, int incolumns)
  {
    rows = inrows;
    columns = incolumns;
    matrix = new double [inrows*incolumns];
    for (int i=0; i<inrows*incolumns; i++) 
    { 
        matrix[i]=0;
    }
  }
  int lengthr() const {return rows;}  //Returns number of rows.
  int lengthc() const {return columns;}   //Return number of columns.
  dymatrix& operator=(dymatrix&);
  ~dymatrix(){cout<<"Destructor called"<<endl;delete[] matrix;}  

  int index(int i, int j)  //This member function returns the position of each index.
  {
    if (j > 0 && j <=rows && i > 0 && i <=columns)
    {
        return (i-1)+(j-1)*columns;
    }
    else {cout<<"Error, out of range"<<endl; exit (1);}
  }
  double & operator()(int i, int j) {return matrix[index(i,j)];}  //The operator () returns the position of j and i in 1D array.

  dymatrix operator + (dymatrix &arr)  //overloading addition.
  {   

    if (rows !=arr.rows && columns != arr.columns)
    {
        cerr<<"SIZE DO NOT MATCH, YOU FAIL"<<endl; exit(1);
    }
    dymatrix new_matrix(rows,columns);
    for (int j = 0; j < arr.rows*arr.columns; j++)
    {
        //for (int i = 1; i <= arr.columns; i++)
        //{
        //cout<<"****"<<j<<endl;    
        new_matrix.matrix[j]= matrix[j]+arr.matrix[j]; //Putting in the data into this dynamic array for each element.
        //}
    }
    return new_matrix;
  }

};  //Class end.
  dymatrix & dymatrix::operator = (dymatrix &arr) //Overloading "=" operator.
  {
    if (&arr == this) return *this; //If the array is the same, no need to change, just to print. The key word "this" is a pointer to the object, and *this gives the object.
    delete[] matrix; matrix =0; rows =0; columns =0;
    rows = arr.rows;   //Setting row length.
    columns = arr.columns;    //Setting column length.
    if(rows*columns > 0)
    {
        matrix = new double [rows*columns]; //Defining a dynamic array here.
        for (int j = 1; j <= rows; j++) //Assigning each term to each term.
        {
            for (int i =1; i <=columns;i++ )
            {
            matrix[index(i,j)] = arr(i,j);  //This is the assigning part, the loop above loops everything so that each term is assigned.
            }
        }
    }
    return *this;   //Return
  }

  istream & operator >> (istream &is, dymatrix &om)   //Overloading ">>" operator here to
  {
    cout<<"Please enter the number of rows you want"<<endl;
    is >> om.rows;  //Inputting number of rows.
    cout<<"Enter the number of columns you want"<<endl;
    is >> om.columns;   //Inputting number of columns.
    cout<<"Enter matrix"<<endl;
    om.matrix = new double [om.rows*om.columns];    //Making a dynamic array here to put the data in.
    for (int j = 1; j <= om.rows; j++)
    {
        for (int i = 1; i <= om.columns; i++)
        {
            is >> om.matrix[om.index(i,j)]; //Putting in the data into this dynamic array for each element.
        }
    }
    return is;
  }
  ostream & operator << (ostream &os,   dymatrix &om)  //To output the matrix in an standard matrix way
  {
    for(int j= 1; j<=om.rows; j++)
    {
        os<<endl<<endl;
        for (int i = 1; i <=om.columns;i++)
        {
            os << om.matrix[om.index(i,j)]<<"\t";   //Similar method used in istream.
        }
    }
    return os;
  }
int main()
{
  dymatrix a1;
  cin >> a1;  //Define the rows of the matrix
  cout << a1<<endl<<endl;
  dymatrix a2;
  cin >> a2;
  cout << a2<<endl<<endl;
  dymatrix resu_a1;
  resu_a1=a1+a2;
  cout<<"Addition = "<<resu_a1<<endl;
  dymatrix resu_a3;
  resu_a3 = a1;
  cout<<"Assigning = "<<resu_a3<<endl;
  return 0;
}  

这是我的析构函数:

~dymatrix(){cout<<"Destructor called"<<endl;delete[] matrix;}  

这是我重载似乎有效的赋值“=”运算符(在 class 之外):

dymatrix & dymatrix::operator = (dymatrix &arr) //Overloading "=" operator.
  {
    if (&arr == this) return *this; //If the array is the same, no need to change, just to print. The key word "this" is a pointer to the object, and *this gives the object.
    delete[] matrix; matrix =0; rows =0; columns =0;
    rows = arr.rows;   //Setting row length.
    columns = arr.columns;    //Setting column length.
    if(rows*columns > 0)
    {
        matrix = new double [rows*columns]; //Defining a dynamic array here.
        for (int j = 1; j <= rows; j++) //Assigning each term to each term.
        {
            for (int i =1; i <=columns;i++ )
            {
            matrix[index(i,j)] = arr(i,j);  //This is the assigning part, the loop above loops everything so that each term is assigned.
            }
        }
    }
    return *this;   //Return
  }

但是当我在 class 中重载加法运算符“+”时,我得到了上面引用的错误。

dymatrix operator + (dymatrix &arr)  //overloading addition.
{   

    if (rows !=arr.rows && columns != arr.columns)
    {
        cerr<<"SIZE DO NOT MATCH, YOU FAIL"<<endl; exit(1);
    }
    dymatrix new_matrix(rows,columns);
    for (int j = 0; j < arr.rows*arr.columns; j++)
    {
        //for (int i = 1; i <= arr.columns; i++)
        //{
        //cout<<"****"<<j<<endl;    
        new_matrix.matrix[j]= matrix[j]+arr.matrix[j]; //Putting in the data into this dynamic array for each element.
        //}
    }
    return new_matrix;
}

这是我的 int main:

int main()
{
  dymatrix a1;
  cin >> a1;  //Define the rows of the matrix
  cout << a1<<endl<<endl;
  dymatrix a2;
  cin >> a2;
  cout << a2<<endl<<endl;
  dymatrix resu_a1;
  resu_a1=a1+a2;
  cout<<"Addition = "<<resu_a1<<endl;
  dymatrix resu_a3;
  resu_a3 = a1;
  cout<<"Assigning = "<<resu_a3<<endl;
return 0;
} 

当您调用 operator + 时,您正在 return 复制矩阵,但是您的 dymatrix 缺少用户定义的复制构造函数:

dymatrix(const dymatrix&);  // this is the missing function

您必须实现此函数才能使 dymatrix 的 return 值正确。如果没有此功能,您的代码将表现出未定义的行为,并且在对象销毁时很可能会崩溃(双重删除错误 and/or 内存泄漏)。

查找 "Rule of 3"。如果实现了自定义的赋值运算符,那么也应该实现自定义的拷贝构造函数和析构函数:

What is The Rule of Three?

最简单的方法是将大部分(如果不是全部)代码从 operator= 移动到复制构造函数。然后使用 copy/swap 惯用语根据复制构造函数实现你的 operator=

What is the copy-and-swap idiom?

至于您对 operator= 的实施:您为什么要做所有这些工作来从一个数组复制到另一个数组?它应该是一个直线循环,从 0 到 rows*columns。您不需要调用所有这些无关的函数来获取 index 等等。

但是回到复制构造函数,它很可能看起来像这样:

#include <algorithm>
//...
dymatrix::dymatrix(const dymatrix& arr) : 
        rows(arr.rows), columns(arr.columns),
        matrix(new double[arr.rows * arr.columns])
{
   std::copy(arr.matrix, arr.matrix + rows*columns, matrix);
}

现在你的赋值运算符可以这样编码:

#include <algorithm>
//...
class dymatrix {
   //...
    dymatrix& operator=(dymatrix arr); // use this version of assignment operator
  //...
};

//...
dymatrix& dymatrix::operator=(dymatrix arr)  
{
   std::swap(rows, arr.rows);
   std::swap(columns, arr.columns);
   std::swap(matrix, arr.matrix);
   return *this;
}

另一点是你应该在实现operator +之前实现operator+=。原因是您可以根据 operator += 编写 operator +,从而创建两个运算符,其中 operator + 本质上是一个 3 行函数(当前 operator + 中的代码将移至 operator +=.


另一点是你的 operator+ 应该传递一个 const dymatrix&,而不是 dymatrix&。您没有在函数内更改参数,因此它应该作为 const 引用传递。


最后一点是,如果添加矩阵时它们的大小不同,您的代码应该抛出异常——它应该 永远不会 只是退出程序代码是这样做的,尤其是不在 class 之内。

这应该可以解释为什么你永远不应该这样做(我知道这可能是一项学校练习,但这样做是一件很糟糕的事情):

exit() call inside a function which should return a reference