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
第一次使用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