2017-10-04 2 views
-1

J'ai créé une classe Matrix au cours de la semaine et j'ai rencontré un problème qui m'a laissé perplexe: l'instruction return d'une de mes fonctions lance une exception bad_array_new_length!Exception C++ bad_array_new_length levée par une instruction return?

est ici un exemple de code que je trouvais ceci:

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. 
     } 
    } 
} 

Faible et voici, quand je lance la fonction qu'il imprime « exception de retour: bad_array_new_length » sur la console.

La fonction a été testé comme ceci:

try 
{ 
    answer = A1 * B1; //A1 and B1 are able to be multiplied. 
} 
catch (const exception& e) 
{ 
    cout << e.what() << endl; 
} 

Le test sert également à récupérer l'exception et elle imprime aussi bien. Après une petite recherche, l'exception bad_array_new_length n'est levée que lorsqu'un tableau reçoit une longueur invalide. La classe Matrix utilise un tableau multidimensionnel pour stocker ses doubles, mais je pense que ce n'est pas la racine du problème car la matrice locale fonctionne parfaitement comme prévu.

Voici comment le tableau multidimensionnel est déclaré et initialisé dans le constructeur, juste au cas où:

//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:

Voici le constructeur de copie définie et d'affectation:

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; 
} 

Par curiosité, j'ai changé le code dans le test seulement:

try 
{ 
    A1 * B1; //Removed assignment to answer Matrix. 
} 
catch (const exception& e) 
{ 
    cout << e.what() << endl; 
} 

..et l'exception encore jeté comme d'habitude.

+0

Tous les chemins de 'Matrix Matrix :: operator * (Matrix & mat)' ne renvoient pas une valeur. – user0042

+0

Votre classe 'Matrix' manque d'un constructeur de copie et d'un opérateur d'affectation définis par l'utilisateur. Ainsi, retourner Matrix est un comportement indéfini en raison d'une corruption de mémoire probable. En outre, vous n'avez pas ou vous n'avez pas montré retourner une valeur dans un ou plusieurs chemins de code de votre 'operator *' - encore une fois, un comportement indéfini. Oh, et si vous avez vraiment écrit un constructeur de copie et un opérateur d'affectation, ne pensez-vous pas que le morceau d'information est la chose la plus importante que vous avez laissée hors de votre poste. puisque tout dépend de ces fonctions à écrire correctement? – PaulMcKenzie

+0

[Quelle est la règle de 3?] (Https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – PaulMcKenzie

Répondre

0

Correction du problème, tout ce que j'avais à faire était de changer la manière dont la mémoire était allouée dans la déclaration de classe et dans le constructeur.