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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    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 Seg fault sur une class matrice
    Bonjour,

    Je programme une classe matrice, héritant d'une classe vecteur (un tableau qui connais sa taille).

    Malheureusement, je me tape un segmentation fault a chaque fois que je veux toucher à ma matrice ... je comprend pas :/

    ___Vecteur

    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
     
    class Vecteur
    {
    	int taille;
    	double* value;
     
    	public:
     
    	Vecteur(int=1);
    	~Vecteur();
            void vectrand(int n=10);
    };
     
    Vecteur::Vecteur(int n)
    {
    	int i;
     
    	taille=n;
    	value = new double[n];
     
    	for(i=0; i<n; i++)
    		value[i]=0;
    }
     
     
    Vecteur::~Vecteur()
    {
    	delete[] value;
    }
     
    void Vecteur::vectrand(int n)
    {
    	int i;
     
    	for(i=0; i<taille; i++)
    		value[i]= rand()%n;
    }
    __Matrice
    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
     
    class Matrice : public Vecteur
    {
    	int line;
    	Vecteur** tvect;
     
    	public:
     
    	Matrice(int col=1, int line=1);
    	void matrand(int n=10);
    	Vecteur& operator[](int)const;
    };
    //Je verrai plus tard pour le destructeur ^^
     
    Matrice::Matrice(int line, int col)
    {
    	int i;
     
    	assert(line>0 && col>0);
     
    	this->line = line;
     
    	Vecteur** tvect = new  Vecteur*[line];
     
    	for(i=0; i<line; i++)
    		tvect[i] = new Vecteur(col);
    }
     
    Vecteur& Matrice::operator[](int i)const
    {
    	return (*tvect)[i];
    }
     
    void Matrice::matrand(int n)
    {
    	int i;
     
    	for(i=0; i<line; i++)
    		(*this)[i].vectrand(n);	
    }

    Merci d'avance !

  2. #2
    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 : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Là, tu te retrouve au final avec quelque chose à trois dimensions, vu que tu as une dimention dans le vecteur et deux autres dans ta matrice... je doute sincèrement que ce soit ce dont tu as besoin

    De plus, tel que ton code apparait, tu mets tout en place pour être confronté à des problèmes sans nom:
    1. Si tu fais une copie de ta matrice (ou ne serait-ce que de ton vecteur!!!), soit te retrouveras avec une double tentative de libération de la mémoire, soit tu te retrouveras à essayer d'accéder à un élément dont la mémoire a été libérée, à un moment ou à un autre
    2. Si l'allocation dynamique au niveau de la matrice échoue pour une raison ou une autre, tu auras une belle fuite mémoire
    3. La classe Matrice est un puits à fuite mémoire, même si tout se passe correctement
    Tous ces problèmes ont déjà été largement abordés à maintes reprises dans le forum, je vais donc te laisser un peu chercher tout seul (mais je suis tout disposé à expliquer le pourquoi du comment en cas de besoin )

    De plus, tu te fais beaucoup de mal pour pas grand chose, dans le sens où une matrice a la particularité remarquable, quand elle est composée de X lignes et de Y colonnes de contenir... X*Y éléments.

    Il est donc tout à fait possible de faire en sorte d'allouer directement l'espace pour ces X*Y éléments "d'une seule traite" .

    A ce moment là, il "suffira" d'utiliser la formule numéro_de_ligne * nombre_de_colonnes + numéro_de_colonne (qui sont autant de données parfaitement connue ) pour accéder à un élément particulier.

    Enfin, La gestion manuelle des allocations et désallocations de mémoire est un domaine où il est particulièrement facile de se tirer une balle dans le pied:
    Si on ne prévoit pas les bons constructeur par copie et opérateurs d'affectation, on se retrouve soit avec des fuites mémoire, soit avec des tentatives de double libération, soit avec des tentatives d'accès à des éléments dont la mémoire a été libérée (ce qui est ton cas), ouvrant la porte à des erreurs de segmentation

    Si on ne prévoit pas le destructeur correct, on se retrouve facilement avec des fuites mémoires (ce qui t'arrive aussi)

    Si on se limite à l'utilisation des pointeurs "nus", il est difficile de savoir "qui fait quoi" (comprends: qui s'occupe de l'allocation de mémoire, qui s'occupe de la libération de la mémoire, qui se repose sur qui pour quoi,...)

    Pour éviter tous ces soucis, C++ fournit, en standard, un ensemble de collections qui sont chacune adaptée à des besoins particuliers.

    Parmi ces collections, il y a entre autre la classe vector, disponible dans l'espace de noms std par simple inclusion du fichier d'en-tête <vector> et qui n'est rien d'autre qu'une encapsulation "correcte" d'un tableau d'éléments contigus en mémoire (ce que tu obtiens avec un new Type[X] ).

    Tu pourrais donc parfaitement envisager d'écrire une classe Matrice sous la forme de
    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
    class Matrice
    {
        public:
            Matrice(size_t lignes, size_t colonnes):internal_(lignes*colonnes),
                                               lignes_(lignes), 
                                               colonnes_(colonnes){}
            /* permet de changer la valeur du double indiqué */
            double & operator()(size_t ligne, size_t colonne)
            {
                assert(ligne < lignes_);
                assert(colonne < colonnes_);
                return interne_[ligne * colones_ + colonne);
            }
            /* accès en "lecture seule" */
            double operator()(size_t ligne, size_t colonne)
            {
                assert(ligne < lignes_);
                assert(colonne < colonnes_);
                return interne_[ligne * colones_ + colonne);
            }
            /* parce que cela peut etre utile ;) */
            size_t lignes() const{return lignes_;}
            size_t colonnes() const{return colonnes_;}
        private:
            std::vector<int> interne_;
            size_t lignes_;
            size_t colonnes_;
    }
    NOTA: je ne crois pas qu'il soit opportun de fournir une fonction membre qui remplisse la matrice de manière aléatoire.

    Ce n'est, à mon sens, pas un service que l'on est en droit d'attendre de la part de la matrice.

    De mon avis personnel, ce serait soit un service que l'on peut attendre de la part des objets qui manipulent la matrice soit un service "totalement indépendant" (une fonction libre ) que l'on peut appeler à notre gré depuis "n'importe où dans le code".

    Enfin, cette classe matrice pourrait être utilisée sous des formes proches de
    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
     
    void fillMatrixRandom(Matrice & mat, int max)
    {
        size_t lignes = mat.lignes();
        size_t colonnes = mat.colonnes();
        for (size_t i = ;i<lignes;++i)
        {
            for(size_t j = 0; j<colonnes; ++j)
            {
                mat(i,j)=rand() %max;
            }
        }
    }
    int main()
    {
        srand();
        Matrice mat( 10, 10);
        fillMatrixRandom(mat, 999);
        for(size_t i = 0;i<10;++i)
        {
            for(size_t j=0;j<10;++j)
            {
                std::cout<<mat(i,j)<<" ";
            }
            std::cout<<std::endl;
        }
    }
    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

  3. #3
    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 pour tout

    Ma prof m'avais conseilé de passer par un pointeur sur un tableau de vecteur, je me rapelle plus pour quoi mais ca me semblais aussi assez compliqué pour pas grand chose ><


    par contre, pour ce qui est de vector, je ne vais pas l'utiliser J'estime que le but de l'apprentissage, c'est de se mettre un peu de baton dans les roues, si j'avais voulu, j'aurai pu DL une classe matrice toute prête et la rendre ...


    merci quand même !

  4. #4
    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 : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Armas Voir le message
    Merci pour tout

    Ma prof m'avais conseilé de passer par un pointeur sur un tableau de vecteur, je me rapelle plus pour quoi mais ca me semblais aussi assez compliqué pour pas grand chose ><
    Encore une prof qui enseigne le C++ comme étant du C with classes!!!

    Proposes lui de faire un tour sur le forum, qu'on puisse essayer de la convaincre de se mettre à jour

    par contre, pour ce qui est de vector, je ne vais pas l'utiliser J'estime que le but de l'apprentissage, c'est de se mettre un peu de baton dans les roues, si j'avais voulu, j'aurai pu DL une classe matrice toute prête et la rendre ...
    Je ne suis mais alors là pas du tout d'accord avec ce principe.

    C++ est un excellent langage, mais il offre déjà bien assez d'occasion de se tirer une balle dans le pied sans devoir en rajouter une couche à chercher la difficulté là où il n'y en a pas besoin.

    Ne t'en fais pas, tu auras plus que largement l'occasion de devoir jouer avec l'allocation dynamique et de t'arracher les cheveux par la suite!

    Mais, avec un peu de chance, tu auras eu l'occasion d'évoluer tant au niveau de la conception qu'au niveau de la connaissance du langage, et, si tu as de la chance, tu seras peut etre en mesure d'identifier les plus gros pièges auxquels tu risques d'être confronté.

    Il y a énormément de marge entre le fait d'apprendre à utiliser ce qui est fourni par le standard et celui d'aller chercher une bibliothèque adaptée à un besoin particulier.

    Le premier cas te permet d'apprendre en n'ayant à t'inquiéter que de ce qui importe réellement (la syntaxe qu'il te faut apprendre, l'algorithmie, l'appréhension du langage, ...) et te servira de toutes manières tout au long de ta carrière de développeur C++, alors que le deuxième est clairement destiné à te faciliter la vie dans ton travail et à t'assurer de travailler avec quelque chose "aussi exempt de bug que possible" (ou du moins, c'est ce que l'on en attend).

    Ne vas pas croire que l'apprentissage du C++ sera "trop facile" si tu utilises la bibliothèque standard! Même en l'utilisant, tu viendras surement nous demander régulièrement des conseils, ne t'en fais pas
    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

  5. #5
    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
    Je crois que mon probleme c'est que je pense toujours au C en programmant ...

    Ma classe matrice n'est toujours pas fonctionnel, je comprend pas -_-"

    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
     
    //a priori, ça marche, en tout cas j'ai pas d'erreur 
     
    Matrice::Matrice(int line, int col)
    {
    	int i;
     
    	assert(line>0 && col>0);
     
    	this->line = line;
     
    	Vecteur* tvect = new  Vecteur[line];
     
    	for(i=0; i<line; i++)
    		tvect[i] = Vecteur(col);
    }
     
    // mais << et rand ne fonctionnent pas et me faire encore un abandon core T_T
     
     
    ostream& operator<<(ostream& o, Matrice m)
    {
    	int i;
     
    	for(i=0; i<m.line; i++)
    		o << m.tvect[i] << endl;		
     
    	return o;
    }
     
    void Matrice::matrand(int n)
    {
    	int i;
     
    	for(i=0; i<line; i++)
    		tvect[i].vectrand(n);	
    }
    Tu peux m'expliquer pourquoi ? Même en regardant attentivement, je vois pas ce qui pose soucis ... j'ai l'impression d'être revenue 1 an en arriere quand j'avais jamais touché au pointeur -_-"

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Utilise std::vector ou std::array (en C++11), qui possèdent les opérations requises: at(i) et size()

    Pour la matrice, commence par coder l'essentiel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class matrice {
    private:
        //ce qui te semble utile
    public:
        matrice(int hauteur, int largeur);//matrice vide
        explicit matrice(int taille);//pour les matrices carrées vides
        ~matrice();
     
        int& operator()(int ligne, int colonne);
        int operator()(int ligne, int colonne) const;
     
        int hauteur() const;
        int largeur() const;
    };
    C'est l'interface que doit avoir la matrice en tant qu'objet mathématique.

    puis rajoute les fonctions libre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    operator*(matrice const & a, matrice const & b);
    matrice operator+(matrice const & a, matrice const & b);
    matrice operator-(matrice const & a, matrice<T> const & b);
    std::vector<int> operator*(matrice const & m, std::vector<int> const & v);
    et la fonction membre int matrice::discriminant() const;.

    Je te conseille de jeter un œil à la faq sur le comment et le pourquoi du matrice::operator()(int ligne, int colonne)
    L'idéal serait les templates:
    Pour la matrice, commence par coder l'essentiel (remplace le template par int si ca te pose problème):
    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
    template <typename T> class matrice {
    private:
        //ce qui te semble utile
    public:
        typedef T element_t;
        matrice(int hauteur, int largeur);//matrice vide
        explicit matrice(int taille);//pour les matrices carrées vides
        ~matrice();
     
        element_t& operator()(int ligne, int colonne);
        const element_t& operator()(int ligne, int colonne) const;
     
        int hauteur() const;
        int largeur() const;
        element_t discriminant() const
    };
     
    template<typename T> operator*(matrice<T> const & a, matrice<T> const & b);
    template<typename T> matrice<T> operator+(matrice<T> const & a, matrice<T> const & b);
    template<typename T> matrice<T> operator-(matrice<T> const & a, matrice<T> const & b);
    template<typename T> std::vector<T> operator*(matrice<T> const & m, std::vector<T> const & v);

  7. #7
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par Armas Voir le message
    Je crois que mon probleme c'est que je pense toujours au C en programmant ...

    Ma classe matrice n'est toujours pas fonctionnel, je comprend pas -_-"

    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
     
    //a priori, ça marche, en tout cas j'ai pas d'erreur 
     
    Matrice::Matrice(int line, int col)
    {
    	int i;
     
    	assert(line>0 && col>0);
     
    	this->line = line;
     
    	Vecteur* tvect = new  Vecteur[line];
     
    	for(i=0; i<line; i++)
    		tvect[i] = Vecteur(col);
    }
     
    // mais << et rand ne fonctionnent pas et me faire encore un abandon core T_T
     
     
    ostream& operator<<(ostream& o, Matrice m)
    {
    	int i;
     
    	for(i=0; i<m.line; i++)
    		o << m.tvect[i] << endl;		
     
    	return o;
    }
     
    void Matrice::matrand(int n)
    {
    	int i;
     
    	for(i=0; i<line; i++)
    		tvect[i].vectrand(n);	
    }
    Tu peux m'expliquer pourquoi ? Même en regardant attentivement, je vois pas ce qui pose soucis ... j'ai l'impression d'être revenue 1 an en arriere quand j'avais jamais touché au pointeur -_-"
    Et que dit le debugger ? (parce que bon, apprendre à coder, c'est bien, mais apprendre à coder sans apprendre à débugger, ça n'est pas très utile... )
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

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