I've been making a Matrix class over the course of the week and have run into a problem that has left me stumped: the return statement of one of my functions is throwing a bad_array_new_length exception!
Here's example code that I used to find this out:
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.
}
}
}
Low and behold, when I run the function it prints out "return exception: bad_array_new_length" onto the console.
The function was tested like so:
try
{
answer = A1 * B1; //A1 and B1 are able to be multiplied.
}
catch (const exception& e)
{
cout << e.what() << endl;
}
The test also catches the exception and prints it out as well.
After doing a little research, the bad_array_new_length exception is only thrown when an array is given an invalid length. The Matrix class does use a multidimensional array to store its doubles, but I would think that this isn't the root of the problem because the local Matrix works perfectly as intended.
Here is how the multidimensional array is declared and initialized in the constructor, just in case:
//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.
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
EDIT:
Here is the defined copy constructor and assignment operator:
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;
}
Out of curiosity, I changed the code in the test to only be:
try
{
A1 * B1; //Removed assignment to answer Matrix.
}
catch (const exception& e)
{
cout << e.what() << endl;
}
..and the exception still threw as normal.