Probleme de memoire avec la bibliothéque matrix.h

Résolu/Fermé
maysa98 Messages postés 1 Date d'inscription vendredi 5 mai 2017 Statut Membre Dernière intervention 5 mai 2017 - Modifié le 26 mai 2017 à 13:05
mamiemando Messages postés 33073 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 avril 2024 - 26 mai 2017 à 13:21
Bonjour,

J'ai un probléme d'allocation de mémoire que je n'arrive pas à résoudre J'espère quelqu'un peut m'aider.

Je manipule des nombres entre 100 et 1000 qui représente dans mon programme des clients ... J'utilise la bibliothèque
Matrix.h


Quand je manipule 100 clients la totalité de mon programme fonctionne. Mais si je teste à partir de 131 clients le programme, se bloque et il m'affiche
Unhandled exception at 0x76f8c41f : Microsoft C++ exception: Numeric_lib::Matrix_error at memory location 0x004bec08
..

J'ai testé et j'ai trouvé qu'à partir d’ici il se bloque :

double gain;
Matrix<int,1>id(n+3); // n : le nombre de clients 
Matrix<int,3>mat(n+1,n+3,3);
//calcul de gain
void calcgain(Matrix<int,1>&id, Matrix<int,1>&nbr, Matrix<double,2>&dis, Matrix<int,3>&arc, Matrix<int,3>&mat);
{ 
 for(int s=1; s<=n; s++)
 {
   id(s)=0;
   for(int i=1; i<=nbr(s)+1; i++)
   { 
    for(int j=i+1; j<=nbr(s)+1; j++)
    { gain=(dis(arc(s,i,1),arc(s,j,1))+dis(arc(s,i,2),(arc(s,j,2))))-(dis(arcb(s,i,1),arc(s,i,2))+dis(arc(s,j,1),arc(s,j,2)));
      if(gain<0)
       { id(s)=id(s)+1;
        mat(s,id(s),1)=arc(s,i,2);
          mat(s,id(s),2)=arc(s,j,1);}}}}}


Merci de m'aider s'il vous plaît !

1 réponse

mamiemando Messages postés 33073 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 avril 2024 7 748
Modifié le 26 mai 2017 à 13:22
Bonjour

Je pense que l'une de tes principales causes de problèmes est que si ton programme était mieux indenté, tu verrais plus facilement des trucs suspects.

double gain;
Matrix<int, 1>id(n+3); // n : le nombre de clients
Matrix<int, 3>mat(n+1, n+3, 3); // <-- (1)

//calcul de gain
void calcgain(
    Matrix<int, 1> & id,
    Matrix<int, 1> & nbr,
    Matrix<double, 2> & dis,
    Matrix<int, 3> & arc,
    Matrix<int, 3> & mat
); // <--- (2)
{
    for(int s = 1; s <= n; s++) // // <--- (3)
    {
        id(s) = 0;
        for(int i=1; i <= nbr(s)+1; i++)
        { 
            for(int j = i + 1; j <= nbr(s) + 1; j++)
            { 
                gain = (
                    dis(arc(s, i, 1), arc(s, j, 1)) +
                    dis(arc(s, i, 2), (arc(s, j, 2)))
                ) - (
                    dis(arcb(s, i, 1), arc(s, i, 2)) + // <--- (4) 
                    dis(arc(s, j, 1), arc(s, j, 2))
                ); // <--- (5)

                if (gain < 0)
                { 
                    id(s) = id(s) + 1;
                    mat(s, id(s), 1) = arc(s, i, 2);
                    mat(s, id(s), 2) = arc(s, j, 1);
                }
            }
        }
    }
}


1) Je suppose que ça n'est pas comme ça dans ton programme, mais en tout cas, en C/C++, du code ne peut exister qu'à l'intérieur d'une fonction.

#include <iostream>

void f() {
  std::cout << "Debut fonction f" << std::endl;
}

int main() {
  std::cout << "Debut du programme" << std::endl;
  return 0;
}


2) Ici tu implémentes une fonction, donc il n'y a pas de
;
derrière
)
. Voir exemple ci-dessus.

3) n n'est pas défini. Ou pour être exact, en C/C++ c'est une très mauvaise habitude de passer une variable globale. Du coup il vaudrait mieux, si cette valeur est nécessaire, que main la passe en paramètre à
calcgain
. Par ailleurs, rien ne garantit une fois que tu entre dans
calcgain
que la matrice est de taille
n
.

4)
arcb
? Pas
arc
?

5)
gain
n'est pas initialisé, donc dans le cas général, il ne vaut pas 0, ta fonction risque de retourner n'importe quoi.

6) De manière générale, il faut t'assurer quand tu itères sur ta matrice (ou un tableau), que tu restes à l'intérieur. Sinon tu commets une erreur dite de débordement de tableau qui se traduit rapidement par une erreur de segmentation (c'est ce qui t'es arrivé).

Pour détecter ce genre d'erreur, utiliser un débogueur permet de savoir exactement quelle ligne à déclenché l'erreur. Généralement ça permet de déduire quel index correspond à une case en dehors du tableau.

Pour résoudre ce genre d'erreur il vaut mieux, quand tu itères sur un tableau, récupérer son index maximum et veiller à ne pas le dépasser.

Exemple :

#include <iostream>
#include <vector>

int main() {
  std::vector<int> v(5);
  for (std::size_t i; i < v.size(); i++) {
    std::cout << v[i] << std::endl;
  }
  return 0;
}


Bonne chance
0