【问题标题】:C++ bad_array_new_length exception thrown by return statement?return 语句引发的 C++ bad_array_new_length 异常?
【发布时间】: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&amp; mat)的所有路径都返回值。
  • 您的Matrix 类缺少用户定义的复制构造函数和赋值运算符。因此,由于可能的内存损坏,返回 Matrix 是未定义的行为。此外,您没有或您没有在operator * 的一个或多个代码路径中显示返回值——再次,未定义的行为。哦,如果你真的写了一个复制构造函数和赋值运算符,你会不会认为信息是你在帖子中遗漏的最重要的东西。因为一切都取决于正确编写这些函数?
  • 今天是 3 或 5 的规则。(移动构造函数和移动赋值都或两者都不是)。但最好是零规则(使用内置 RAII 以避免编写任何这些 - 在可能的情况下)。

标签: c++ exception multidimensional-array return


【解决方案1】:

解决了这个问题,我所要做的就是改变在类声明和构造函数中分配内存的方式。

【讨论】:

    猜你喜欢
    • 2016-08-18
    • 2011-04-15
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    相关资源
    最近更新 更多