矩阵类错误:表达式:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)

时间:2015-03-06 00:44:31

标签: c++ oop c++11

这是我第一次使用stackoverflow,很高兴认识你们。 我正在编写一个重载赋值,加法,减法等的矩阵类。 赋值运算符“=”重载部分似乎工作正常,但如果我尝试重载添加“+”运算符,我会收到如下错误消息:

“调试断言失败! 程序:... 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;}  

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

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
  }

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

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()
{
  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;
} 

1 个答案:

答案 0 :(得分:0)

当您致电operator +时,您将返回矩阵的副本,但您的dymatrix缺少用户定义的副本构造函数:

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

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

查看&#34;规则3&#34;。如果实现用户定义的赋值运算符,则还应实现用户定义的复制构造函数和析构函数:

What is The Rule of Three?

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

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引用传递。


最后一点是,如果添加它们时矩阵的大小不同,那么代码应该抛出异常 - 它应该永远不会只是像代码一样退出程序,并且特别是不在课堂上。

这应该可以解释为什么你不应该这样做(我知道这可能是学校练习,但这样做很糟糕):

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