IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Seg fault sur une class matrice


Sujet :

C++

  1. #21
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 28
    Par défaut
    J'ai modifié
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ostream& operator<<(ostream& o, Matrice m)
    {
    	int i;
     
    	for(i=0; i<m.line; i++)
    		o << m.tvect[i] << endl;		
     
    	return o;
    }
    en

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ostream& operator<<(ostream& o, const Matrice& m)
    {
    	int i;
     
    	for(i=0; i<m.line; i++)
    		o << m.tvect[i] << endl;		
     
    	return o;
    }
    Mais ça change rien ...

    Si je ne me trompe pas, le passage par valeur sert (en gros) à calculer/afficher des operations sans modifier l'objet envoyé dans la fonction, tandis que le passage par reference (avec un & dans le prototype) permet d'en modifier la valeur, en plus d'optimiser le code par un gain de temps (moins de données à copier dans la pile).

    Mais je vois pas ce que ça a a faire ici

  2. #22
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 356
    Billets dans le blog
    2
    Par défaut
    Ok, je t'ai dit une bêtise hier. Mais laisse tout de même la version const Matrice &, c'est plus standard.

    En fait, le problème est un peu plus fourbe. Tout vient de la façon dont sont construits les vecteurs dans les matrices. Tu les construit en 3 temps:
    1. tu les déclares (dans la déclaration de la classe)
    2. tu les alloues:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tvect = new Vecteur[line];
    3. tu les initialises:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(int i = 0; i < line; i++ )
       tvect[i] = Vecteur(col);
    Le problème c'est que lors de l'allocation, c'est le constructeur par défaut qui est appelé, donc avec n=1. Donc la variable membre taille de Vecteur est affectée à 1. Et après elle n'est plus modifiée, donc elle reste à 1.

    Une façon rapide de réparer ça c'est de remettre à jour cette variable membre taille à chaque fois qu'il le faut, c'est à dire, en gros, à chaque fois que le tableau Vecteur::value est modifié.

  3. #23
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 28
    Par défaut
    Merci, mais j'avais trouvé l'erreur ce matin

    Et au final ca n'a plus d'importance, je vais retourner sur la methode que m'a expliqué ma prof, elle avait bien raison au final ^^

    fallait faire un Vecteur** tvect (pointeur sur tableau de vecteur) pour pouvoir réellement alloué dynamiquement la matrice, sans passer par de petites "entourloupes" au langage comme je l'avais fait ^^

    Mais du coup ça complique quand même mes autre methodes et surtout mon delete qui chie encore dans la colle :'( tu pourrai m'aider pour ça ?

  4. #24
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Re...

    Non, l'idéal, ca reste de n'avoir qu'une seule classe et de considérer qu'une matrice de X lignes et Y colonnes est en réalité un tableau composé de X*Y éléments.

    Quitte, si tu ne veux absolument pas utiliser std::vector, et bien que je ne peux que t'inciter très fortement à l'utiliser, à utiliser l'allocation dynamique, mais en veillant dans ce cas à respecter la règle des trois grands:
    Si, pour une raison ou une autre, il faut donner une implémentation particulière à l'une des fonctions parmi le constructeur par copie, l'opérateur d'affectation ou le destructeur, alors, il faut fournir une implémentation particulière pour chacune de ces fonctions
    Ainsi, ta classe Matrice pourrait elle ressembler à quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    class Matrice
    {
        public:
            Matrice(int ligne, int colonne):lignes_(ligne),colonnes_(colonne),tab_(new double[ligne*colonne]){}
           ~Matrice(){delete tab_;}
           // j'ai fourni une implémentation particulière au destructeur, je dois 
           // donc fournir une implémentation particulière au constructeur
           // par copie et à l'opérateur d'affectation
           Matrice(Matrice const & rhs):lignes_(rhs.lignes),colonnes_(rhs.colonnes), tab_(new double rhs.lignes_*rhs.colonnes_)
           {
                memcpy(tab_,rhs.tab_,lignes_*colones_ * sizeof(double));
            }
            Matrice & operator = (Matrice const & rhs)
            {
                Matrice temp(rhs); // crée une copie de la matrice à affecter
                swap(temp); //interverti les membres de la copie et de l'objet courent
                return *this;
            } //temp est détruit ici, le tableau alloué dynamiquement d'origine est bien libéré
            /* l'accès "en lecture seule" à un élément donné */
            double itemAt(int linge, int colonne) const
            {
                  return tab_[ligne * colonnes_ + colonne];
            }
            /* l'accès "en écriture" à un élément donné */
            double& itemAt(int linge, int colonne) 
            {
                  return tab_[ligne * colonnes_ + colonne];
            }
            /* et parce que ca peut etre utile, l'opérateur de flux de sortie, 
                et la possibilité de récupérer le nombre de lignes et de colonnes
             */
            std::ostream & operator <<(ostream & os)
            {
                 for(int i = 0;i<lignes_;++i)
                 {
                     for(int j = 0;j<colonnes_;++j)
                     {
                         os<<itemAt(i, j)<<" ";
                     }
                     os<<std::endl;
                 }
                 return os;
            }
            int lignes() const{return linges_;}
            int colonnes() const{return colonnes_;}
        private:
            int linges_;
            int colonnes_;
            double tab_;
            void swap(Matrice & other) // la "partie magique" de l'opérateur d'affectation :D
             {
                  std::swap(lignes_, other.lignes_);
                  std::swap(colonnes_,other.colonnes_);
                  std::swap(tab_,other.tab_);
             }
    };
    Le tout pouvant être utilisé de manière assez simple sous la forme de
    int main()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    {
        Matrice mat(10, 12);
        /* si on veut remplire la matrice, on peut s'amuser à quelque 
         * chose comme
         */
        for(int i = 0;i<mat.lignes(); ++i)
        {
            for(int j = 0;j<mat.colonnes(); ++j)
            {
                mat.itemAt(i, j) = /* valeur à donner à l'élément */;
            }
        }
        /* si l'opérateur << ne nous convient pas telle qu'implémenté, on peut
         * accéder aux éléments de la matrice sous la forme de
      
        for(int i = 0;i<mat.lignes(); ++i)
        {
            for(int j = 0;j<mat.colonnes(); ++j)
            {
                std::cout<<"element en "<<i<<" "<<j<<" = "<<mat.itemAt(i, j);
            }
            std::cout<<std::endl;
        }
        return 0;
    }
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Réponses: 10
    Dernier message: 05/12/2005, 01h25
  2. [C++] pointeur sur une classe
    Par PH69 dans le forum Débuter
    Réponses: 1
    Dernier message: 21/11/2005, 22h08
  3. Création dynamique de méthode sur une classe ?
    Par elitost dans le forum Général Java
    Réponses: 9
    Dernier message: 18/10/2005, 14h47
  4. Réponses: 14
    Dernier message: 14/03/2005, 09h16
  5. [MFC] Problème pointeur sur une classe
    Par mick74 dans le forum MFC
    Réponses: 7
    Dernier message: 14/04/2004, 14h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo