Partage
  • Partager sur Facebook
  • Partager sur Twitter

problème allocation de mémoire

Sujet résolu
    3 mai 2022 à 19:53:35

    Bonsoir,

    Dans le cadre d'un projet perso je tente d'implémenter les règles de calculs matriciel pour la résolution d'une EDP. Seulement lorsque je lance le programme (même pas achevé, c'est juste le test du schéma avec des matrices nulles), j'ai le message d'erreur suivant :

    "malloc_consolidate(): invalid chunk size
    Abandon (core dumped)
    "

    Mes connaissance en matière de mémoire sont quasi nulle. Je ne comprend pas le problème de mon code (ci dessous).

    En vous remerciant par avance de l'aide que vous pourrez m'apporter.

    #include <iostream>
    #include <cmath>
    #include <fstream>
    #include <stdlib.h>
    #include<string>
    using namespace std;
    //classe de matrice
    class mat
    {
     private :
     int n;
     int m;
     double** M; //matrice nxm
     
     public:
     mat();
     ~mat();
     mat(int,int,string);
     mat(int,int);
     mat &operator=(const mat&);
     
     //accesseur:
     int get_n() const;
     int get_m() const;
     double getc(const int&, const int&) const; //donne la coordonnée i,j de la matrice en question
     void show() const; //affiche la matrice
     
     
     //mutateur:
     void set_n(int u);
     void set_m(int v);
     void setc(int , int , double );
     
     //Caclul matriciel+surcharge des opérateurs +,*,=:
     mat &operator+=(const mat&); //addition matriciel
     friend mat operator+(const mat& A, const mat& B);
     friend mat operator*(const mat& A, const mat& B);
    };
    
    //===================Constructeurs=======================
     mat::mat(int u, int v, string s) //constructeur, créé un tableau et le remplie.
     {
       set_n(u);
       set_m(v);
       M=new double*[n];
      for(int i=0;i<n;i++)
      {
       M[i]=new double[m];
      }
      //matrice dimensionnée
      ifstream ifile(s);
       
       for(int i=0;i<n;i++)
       {
        for(int j=0;j<m;j++)
        {
         ifile>>M[i][j];
        }
       }
      ifile.close();
     }
    
    
     mat::~mat() //destructeur désaloue la mémoire.
     {
      for(int j=0;j<m; j++)
      {
       delete[] M[j];  //désaloue les pointeurs de M
      }
      
      delete[] M; //désaloue le tableau en lui même
     }
    
     mat &mat::operator=(const mat& A) //constructeur de recopie, copie A sur M. A est pris en alias, et constant. M est pris en alias.
     {
     
     if(n!=A.get_n() || m!=A.get_m())
     {
      cout<<"erreur de dimension dans l'égalité matriciel"<<endl;
      abort();
     }
     
     if(this != &A) //On vérifie que ça ne soit pas le même pointeur.
      for(int i=0;i<n;i++)
      {
       for(int j=0;j<n;j++)
       {
      this->setc(i,j, A.getc(i,j));
       }
      }
      return *this;
     }
     
     mat::mat(int u,int v) //créé une matrice nulle
     {
       set_n(u);
       set_m(v);
       M=new double*[n];
      for(int i=0;i<n;i++)
      {
       M[i]=new double[m];
      }
      
      for(int i=0;i<n;i++)
      {
       for(int j=0;j<m;j++)
       {
        this->setc(i,j,0);
       }
      }
     }
     
     //====================accesseur============================
     
     int mat::get_n() const
     {
      return n;
     }
     
     int mat::get_m() const
     {
      return m;
     }
     
     
     
     double mat::getc(const int& i,const int& j) const
     {
      return M[i][j];
     }
     
     void mat::show() const
     {
      for(int i=0;i<n;i++)
      {
       for(int j=0;j<m;j++)
        {
         cout<<M[i][j]<<" ";
        }
        cout<<endl;
      }
      cout<<endl;
     }
     
    // ==========Methode des mutateurs==========
     void mat::set_n(int u)
     {
      n=u;
     }
     
      void mat::set_m(int v)
     {
      m=v;
     }
     
     void mat::setc(int i, int j, double m)
     {
      M[i][j]=m;
     }
     
    //===========Methode de calcul matriciel (opérateurs surchargé)================== 
    
     mat &mat::operator+=(const mat& A)
     {
      if(this->get_n()!=A.get_n() || this->get_m()!=A.get_m() )
      {
       cout<<"erreur dimension addition matriciel"<<endl;
       abort();
      }
     
     
      for (int i=0;i<n;i++)
      {
       for(int j=0;j<n;j++)
       {
        this->setc(i,j,this->getc(i,j)+A.getc(i,j));
       }
      }
     
      return *this;
     }
     
     mat operator+(const mat& A, const mat& B)
     {
      mat C(A.get_n(),A.get_m());
      C=A;
      C+=B;
      return C;
     }
     
     
     mat operator*(const mat& A, const mat& B)
     {
      if(A.get_m()!=B.get_n())
      {
       cout<<"erreur dimension produit matriciel"<<endl;
       abort();
      }
      
      
      mat C(A.get_n(),B.get_m());
      for(int i=0;i<C.get_n();i++)
      {
       for(int j=0;j<C.get_m();j++)
       {
        for(int k=0;k<A.get_m();k++)
        C.setc(i,j,C.getc(i,j)+A.getc(i,k)*B.getc(k,j));
       }
     
      }
       
      
      
       return C;
     
     }
     
     
    
    
    void initialise_A(mat& A, double a, double b, double c, int I);
    void initialise_B(mat& B, double t, double b, double c, int I);
    void initialise_V(mat& V,int I);
    
    
    
    
    
    
    
    
      
    
    int main()
    {
     
    //Conditions initiales du problème 1D+constantes physiques
     double u=20.; //Conditions au bord type Dirichlet
     double T=1000.; //temps maximal de l'expérience
     double D=10.;//Taille de l'espace
     double K=0.023;
    //Paramétrage du problème
     double dt=10.;//pas de temps
     double dx=1.;//pas de l'espace
     double x=0.;//initialisation de la variable d'espace
     double t=0.;
     double f=K*(dt/pow(dx,2));//facteur de stabilité doit être inférieur à 2. Sinon instable.
     int I=floor(D/dx);//discrérisation en J cellules de l'espace
     int N=floor(T/dt);//discrétisation en N cellules de temps
     //constantes du schémas numérique.
     double b=(dt/pow(dx,2))*K;
     double a=-2*K*(dt/pow(dx,2));
     double c=b;
     //création du schéma numérique :
     int P=I-2;
    //matrice du schémas
     mat A(P,P);
     mat V(P,1);
     mat B(P,1);
     mat W(P,1);
     A.~mat();
     V.~mat();
     B.~mat();
    //boucle du schemas.
     for(int n=0;n<N;t++)
     {
      W=A*V+B;
      V=W;
      t+=n*dt;
     }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    return 0;
    }
    
    void initialise_A(mat& A, double a, double b, double c, int I)
    {
     for(int i=1;i<I-1;i++)
      {
       A.setc(i,i,a);
       A.setc(i,i+1,b);
       A.setc(i+1,i,c);
      }
     A.setc(0,0,a);
     A.setc(0,1,b);
     A.setc(1,0,c);
     A.setc(I-1,I-1,a);
    }
    
    
    void initialise_B(mat& B, double t, double b, double c, int I)
    {
     for(int i=0;i<I-1;i++)
     {
      B.setc(i,0,0);
     }
     B.setc(0,0,c*t);
     B.setc(I-1,0,b*t);
    }
    
    
    
    void initialise_V(mat& V,int I)
    {
     for(int i=0;i<I;i++)
     {
      V.setc(i,0,23);
     }
    }
    
    
    
    
    





    • Partager sur Facebook
    • Partager sur Twitter
      3 mai 2022 à 20:26:46

      Je n'ai pas regardé en détail, mais dans ta fonction main, tu appelles explicitement les destructeurs, ça ne ce fait pas. et en plus ensuite tu utilises encore les objets en question.
      • Partager sur Facebook
      • Partager sur Twitter
        3 mai 2022 à 21:29:58

        Bonsoir

        Tu aurais pu utiliser autre chose(std::vector<std::vector<double>>, std::array, ou autre collection) que double** pour représenter ta matrice.

        Sinon tu peux déboguer ton code ligne par ligne et voir a quel niveau l'erreur est levée

        -
        Edité par Asmitta 3 mai 2022 à 21:33:56

        • Partager sur Facebook
        • Partager sur Twitter
          4 mai 2022 à 0:27:39

          Et si tu commençait par faire moderne en virant tous ces horribles pointeur nu tout moisi ?

          Les conteneurs de la STL sont tes amis, et si tu n'en veux pas, passe par les pointeurs intelligents, tu n'en tireras que des avantages.

          • Partager sur Facebook
          • Partager sur Twitter
            4 mai 2022 à 9:46:42

            Merci à tous les trois pour vos réponses.
            • Partager sur Facebook
            • Partager sur Twitter
              4 mai 2022 à 9:57:53

              boblegardois a écrit:

              Merci à tous les trois pour vos réponses.

              Bonjour,

              Sujet résolu

              Tu peux passer le sujet à "résolu" (bouton en haut à droite du sujet) et cliquer sur les pouces levés des messages qui t'ont aidé⋅e ;)

              • Partager sur Facebook
              • Partager sur Twitter

              problème allocation de mémoire

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown