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 :

Message d'erreur ! Je ne sais pas d'où il vient.


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 53
    Points : 22
    Points
    22
    Par défaut Message d'erreur ! Je ne sais pas d'où il vient.
    Bonjour,

    Voilà, je dois créer une classe Etudiant permettant d'y enregistrer son matricule,le nombre de cours qu'il suit, ainsi que les notes relatives à chacun des cours( dans un vecteur créé dynamiquement). Ainsi que des méthodes qui permettront d'y accéder. Je dois utiliser les types de données abstraits.

    Voilà mes différents fichiers :

    Mon hpp:
    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
    class Etudiant
    {
    	public:
    		double moyenneNotes() ;
    		int obtenirMatricule() ;
    		int obtenirNombreCours() ;
    		int obtenirNote(int numCours);
    		Etudiant ();
    		Etudiant (int mat,int nombreCoursSuivis,int V[]);
    		Etudiant& operator/=(const Etudiant &);
    		~Etudiant();
     
    	private:
    		int matricule;
    		int nombreCours;
    		int *vecteur;
    };
    Mon cpp Etudiant:
    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
    57
    58
    59
    #include "etudiant.hpp"
     
    Etudiant::Etudiant()
    {
    	matricule=0;	
    	nombreCours=0;
    	vecteur=0;
    }
     
    Etudiant::Etudiant(int mat,int nombreCoursSuivis,int V[])
    {
    	matricule=mat;
    	nombreCours=nombreCoursSuivis;
    	vecteur=new int[nombreCours];
    	for (int i=0;i<nombreCours;++i)
    		vecteur[i]=V[i];
    }
     
    int Etudiant::obtenirMatricule() 
    {
    	return matricule;
    }
     
    int Etudiant::obtenirNote(int numCours) 
    {
    	return vecteur[numCours-1];	
    }
     
    int Etudiant::obtenirNombreCours() 
    {
    	return nombreCours;
    }
     
     
    double Etudiant::moyenneNotes() 
    {
    	double somme=0;
    	for (int i=0;i<nombreCours;i++)
    		somme+=vecteur[i];
    	return (somme/nombreCours);	
    }
     
     
    Etudiant& Etudiant::operator/=(const Etudiant &e)
    {
    	if(&e!=this)
    	{
    		matricule=e.matricule;
    		nombreCours=e.nombreCours;
    		for (int i=0;i<nombreCours;++i)
    			vecteur[i]=e.vecteur[i];
    	}
    	return (*this);	
    }
     
    Etudiant::~Etudiant()
    {
    	delete[] vecteur;
    }
    Mon 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
    #include <iostream>
    #include "etudiant.hpp"
    using namespace std;
     
     
    int main()
    {
    	int matriculeX=3526,nbreCoursX=5,numCours=2;
     
    	int V[5]={8,6,10,12,8};
    	Etudiant x(matriculeX,nbreCoursX,V);
    	cout<< x.obtenirNote(numCours)<<endl;
    	cout<< x.moyenneNotes()<<endl;
    	Etudiant y;
    	y=x;
    	cout << y.moyenneNotes() << endl;
    	cout << y.obtenirNote(4) << endl;
    	return 0;
     
    }
    Je n'ai pas de problème à la compilation mais à l'exécution , j'obtiens ce message d'erreur :
    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
    *** glibc detected *** ./dev.exe: double free or corruption (fasttop): 0x09824008 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0xb7e84454]
    /lib/tls/i686/cmov/libc.so.6(cfree+0x96)[0xb7e864b6]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb80620b1]
    /usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb806210d]
    ./dev.exe[0x80488ea]
    ./dev.exe[0x8048b8d]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7e2b685]
    ./dev.exe[0x8048701]
    ======= Memory map: ========
    08048000-08049000 r-xp 00000000 08:01 3153998    /home/aurelien/Bureau/ProjetsINFO/dev.exe
    08049000-0804a000 r--p 00000000 08:01 3153998    /home/aurelien/Bureau/ProjetsINFO/dev.exe
    0804a000-0804b000 rw-p 00001000 08:01 3153998    /home/aurelien/Bureau/ProjetsINFO/dev.exe
    09824000-09845000 rw-p 09824000 00:00 0          [heap]
    b7d00000-b7d21000 rw-p b7d00000 00:00 0 
    b7d21000-b7e00000 ---p b7d21000 00:00 0 
    b7e14000-b7e15000 rw-p b7e14000 00:00 0 
    b7e15000-b7f6d000 r-xp 00000000 08:01 12763218   /lib/tls/i686/cmov/libc-2.8.90.so
    b7f6d000-b7f6f000 r--p 00158000 08:01 12763218   /lib/tls/i686/cmov/libc-2.8.90.so
    b7f6f000-b7f70000 rw-p 0015a000 08:01 12763218   /lib/tls/i686/cmov/libc-2.8.90.so
    b7f70000-b7f73000 rw-p b7f70000 00:00 0 
    b7f73000-b7f80000 r-xp 00000000 08:01 12746773   /lib/libgcc_s.so.1
    b7f80000-b7f81000 r--p 0000c000 08:01 12746773   /lib/libgcc_s.so.1
    b7f81000-b7f82000 rw-p 0000d000 08:01 12746773   /lib/libgcc_s.so.1
    b7f82000-b7f83000 rw-p b7f82000 00:00 0 
    b7f83000-b7fa7000 r-xp 00000000 08:01 12763224   /lib/tls/i686/cmov/libm-2.8.90.so
    b7fa7000-b7fa8000 r--p 00023000 08:01 12763224   /lib/tls/i686/cmov/libm-2.8.90.so
    b7fa8000-b7fa9000 rw-p 00024000 08:01 12763224   /lib/tls/i686/cmov/libm-2.8.90.so
    b7fa9000-b808c000 r-xp 00000000 08:01 7577942    /usr/lib/libstdc++.so.6.0.10
    b808c000-b8090000 r--p 000e3000 08:01 7577942    /usr/lib/libstdc++.so.6.0.10
    b8090000-b8091000 rw-p 000e7000 08:01 7577942    /usr/lib/libstdc++.so.6.0.10
    b8091000-b8097000 rw-p b8091000 00:00 0 
    b80a7000-b80aa000 rw-p b80a7000 00:00 0 
    b80aa000-b80c4000 r-xp 00000000 08:01 12746771   /lib/ld-2.8.90.so
    b80c4000-b80c5000 r-xp b80c4000 00:00 0          [vdso]
    b80c5000-b80c6000 r--p 0001a000 08:01 12746771   /lib/ld-2.8.90.so
    b80c6000-b80c7000 rw-p 0001b000 08:01 12746771   /lib/ld-2.8.90.so
    bffb2000-bffc7000 rw-p bffeb000 00:00 0          [stack]
    Abandon
    Ce message n'apparait que lorsque j'ajoute un destructeur comme c'est le cas dans les codes plus hauts! Lorsque que je ne mets pas de destructeur je n'ai pas ce message. Donc j'ai du oublier quelque chose là dedans.

    Des idées ??

    Merci!

  2. #2
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Dans ton constructeur par défaut, tu ne crée pas de vecteur (pas d'appel à new). Or une partie de ton main (étudiant y) ne demande pas la création de ce vecteur. Tu fais donc un appel à delete sans avoir appelé de new. BOUM !
    Le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Etudiant::~Etudiant()
    {
        if (vecteur)
    	delete[] vecteur;
    }
    te permettra d'éliminer ton problème.
    MAIS ton code sera toujours inexact. Pourquoi ?
    ce code nécessite l'opérateur =, et tu ne l'as pas défini...

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Comme tu as une allocation dynamique dans le constructeur, tu devrais redéfinir le constructeur par copie également, et veiller à ce que cette allocation dynamique ait bien lieu dedans...

    En effet, si tu ne le fait pas, les différents membres d'étudiants seront copiés membre à membre, ce qui signifie qu'ils partageront la même adresse pour le tableau alloué dynamiquement.

    Le résultat est que, lorsqu'une copie sera effectuée et que l'une des variable (que ce soit la copie ou l'originale) sera détruite, tu aura une première libération de la mémoire allouée à ce tableau, qui deviendra - de facto - invalide pour la variable "survivante" et que tu auras une "double libération de la mémoire" lorsque cette variable survivante sera détruite à son tour.

    De plus, j'espère que ce n'est qu'une erreur de copie, mais c'est l'opérateur = qu'il faut définir et non l'opérateur /= (l'idéal étant d'utiliser l'idiome "copy and swap" pour le redéfinir)

    Enfin, tu pourrais t'éviter bien des soucis si tu décidais d'utiliser la classe vector (par exemple) plutôt que l'allocation dynamique pour ton tableau
    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

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 53
    Points : 22
    Points
    22
    Par défaut
    J'ai suivi ce que vous m'avez conseillé, je n'obtiens plus ce message

    Merci beaucoup !

    ps: je ne comprend pas très bien la différence entre l'opérateur = et /= ??

  5. #5
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    L'operateur = est l'opérateur qui permet de faire une affectation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    x = 4;
    etudiant1 = etudiant2;
    L'opérateur /= est un opérateur qui permet de faire une division
    peut être remplacé par
    Effectivement dans ton code, tu a définis un opérateur /= mais je ne suis pas sûr que ce soit le sens que tu veuilles lui donner. Un opérateur = serait mieux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Etudiant& Etudiant::operator = (const Etudiant &e)
    {
       matricule = e.matricule;
       nombreCours = e.nombreCours;
       for (int i = 0; i < nombreCours; ++i)
          vecteur[i] = e.vecteur[i];
       return (*this);
    }
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Attention, ram, vector est un tableau alloué dynamiquement... faut pas l'oublier

    Du coup, l'idiome copy and swap semble particulièrement adapté

    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
    Etudiant::Etudiant(Etudiant const & e):
              matricule(e.matricule),nombreCours(e.nombreCours),
              vecteur(new int[nombreCours])
    {
        for(size_t i = 0;i<nombreCours;++i)
            vecteur[i]=e.vecteur[i];
    }
    Etudiant& operator = (Etudiant const & e)
    {
        Etudiant temp(e);
        std::swap(matricule,e.matricule);
        std::swap(nombreCours, e.nombreCours);
        std::swap(vecteur,e.vecteur);
        return *this;
    }
    (cf le lien de mon post précédent parce que l'idéal serait d'utiliser le non throwing swap )

    Attention, cela nécessite l'inclusion de <algorithm>
    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. [Débutant] message d'erreur: word n'a pas pu ouvrir le document
    Par leoppina dans le forum ASP.NET
    Réponses: 2
    Dernier message: 29/08/2011, 20h09
  2. [MySQL] Message d'erreur ne s'affiche pas !
    Par CaLeDo dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 17/07/2007, 01h10
  3. [Oracle] erreur mais je ne sais pas d'où ça vient
    Par teen6517 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 27/02/2007, 08h52
  4. Message d erreur qd je suis pas sur la bonne feuille
    Par johndeuf dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 07/12/2006, 22h58
  5. Réponses: 2
    Dernier message: 29/05/2006, 12h43

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