【发布时间】:2018-03-15 08:04:24
【问题描述】:
这周我一直在做一个 Matrix 类,但遇到了一个让我很困惑的问题:我的一个函数的 return 语句抛出了 bad_array_new_length 异常!
这是我用来找出这个问题的示例代码:
Matrix Matrix::operator*(Matrix& mat)
{
if (this->columns != mat.rows)
{
//Do code if Matrix can't be multiplied.
}
else
{
Matrix result(this->rows, mat.columns);
//Multiply Matrices together.
//Print out result to prove the local Matrix works fine.
//It does.
try
{
return result;
}
catch (const exception& e)
{
cout << "return exception: " << e.what() << endl;
return result; //To be caught again in the test.
}
}
}
瞧,当我运行该函数时,它会在控制台上打印出“返回异常:bad_array_new_length”。
函数是这样测试的:
try
{
answer = A1 * B1; //A1 and B1 are able to be multiplied.
}
catch (const exception& e)
{
cout << e.what() << endl;
}
该测试还捕获异常并将其打印出来。
经过一番研究,bad_array_new_length 异常仅在数组被赋予无效长度时抛出。 Matrix 类确实使用多维数组来存储其双精度数,但我认为这不是问题的根源,因为本地 Matrix 可以按预期完美运行。
下面是在构造函数中声明和初始化多维数组的方式,以防万一:
//Matrix.h
unsigned int rows;
unsigned int columns;
double ** storage = new double*[rows]; //Multidimensional array isn't completely formed, see the constructor.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Matrix.cpp
Matrix::Matrix(unsigned int x, unsigned int y)
:
rows(x),
columns(y)
{
for (unsigned int i = 0; i < rows; ++i) //Completes the formation of the multidimensional array.
storage[i] = new double[columns];
for (unsigned int i = 0; i < rows; ++i)
{
for (unsigned int q = 0; q < columns; ++q)
{
storage[i][q] = 0; //Initializes each value in the array as 0.
}
}
}
/////////////////////////////////////// ///////////////////////////////////////// ////
编辑:
这里是定义的拷贝构造函数和赋值运算符:
Matrix::Matrix(const Matrix& obj)
{
rows = obj.rows;
columns = obj.columns;
for (unsigned int i = 0; i < rows; ++i)
{
for (unsigned int q = 0; q < columns; ++q)
{
storage[i][q] = obj.storage[i][q];
}
}
}
////////////////////////////////////////////////////////////////////////////////
bool Matrix::operator=(Matrix mat)
{
rows = mat.rows;
columns = mat.columns;
for (unsigned int i = 0; i < rows; ++i)
{
for (unsigned int q = 0; q < columns; ++q)
{
storage[i][q] = mat.storage[i][q];
}
}
return true;
}
出于好奇,我将测试中的代码改为:
try
{
A1 * B1; //Removed assignment to answer Matrix.
}
catch (const exception& e)
{
cout << e.what() << endl;
}
..异常仍然正常抛出。
【问题讨论】:
-
并非
Matrix Matrix::operator*(Matrix& mat)的所有路径都返回值。 -
您的
Matrix类缺少用户定义的复制构造函数和赋值运算符。因此,由于可能的内存损坏,返回Matrix是未定义的行为。此外,您没有或您没有在operator *的一个或多个代码路径中显示返回值——再次,未定义的行为。哦,如果你真的写了一个复制构造函数和赋值运算符,你会不会认为信息是你在帖子中遗漏的最重要的东西。因为一切都取决于正确编写这些函数? -
今天是 3 或 5 的规则。(移动构造函数和移动赋值都或两者都不是)。但最好是零规则(使用内置 RAII 以避免编写任何这些 - 在可能的情况下)。
标签: c++ exception multidimensional-array return