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 :

Fuite de mémoire et agrégation


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2013
    Messages : 2
    Par défaut Fuite de mémoire et agrégation
    Bonjour,
    J'ai un petit problème au niveau des fuites de mémoire. J'ai une classe Vidéothèque, une classe Coffret et une classe Film. La classe vidéothèque a comme attribut un pointeur vers un tableau dynamique de coffret (Coffret*) qui est alloué dans le constructeur par défault. Chaque coffret à un pointeur vers un tableau dynamique de films(Film*) qui est aussi alloué dans le constructeur par défault. Puisque une image vaut mille mots en voici une :



    Lorsque le programme termine, il appelle le destructeur par défault de Vidéothèque où je fais : delete []tableauCoffret_; Selon ce que je comprends, le destructeur de vidéothèque appelle donc le destructeur de coffret qui est : delete []tableauFilm_;. Ensuite, celui-ci appelle le destructeur de Film qui est vide{}. Malheureusement, cela ne fonctionne pas et j'ai une erreur lors de l'éxécution à la fin du programme lors de l'appel du destructeur de vidéotheque.

    File dbgdel.cpp line 52 expression L: _BLOCK_type_is_VALID(Phead->nblockuse)

    Pourriez-vous m'éclairer sur mon erreur avec les destructeurs , merci beaucoup. Voici les destructeurs et constructeurs par défault de chacune des classes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Videotheque::Videotheque()
    {
    	tableauCoffret_ = new Coffret[6];
    }
    Videotheque::~Videotheque()
    {
    	delete [] tableauCoffret_;
    	tableauFilm_=0;
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Coffret::~Coffret()
    {
    	delete [] tableauFilm_;
    	tableauFilm_=0;
     
    }
    Coffret::Coffret()
    {
    	tableauFilm_ = new Film[6];
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Film::Film()
    {
     // tout simplement vide
    }
    Film::~Film()
    {
     // tout simplement vide
    }

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Je suppose qu'à un moment tu copies une de tes instances d'une de tes classes.
    Or la copie est quelque peut "bête" si te le l'as pas défini toi-même, elle se contentera de copier le contenu de ton objet octet par octet.

    Ainsi tu aura deux instances ayant un pointeur vers une même zone allouée.
    Or comme tu as deux instances, tu va appeler 2 fois le destructeurs ce qui va poser problème lors du delete[] du deuxième destructeur appelé.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2013
    Messages : 2
    Par défaut
    Bonjour,
    Merci de votre réponse, je ne suis pas certain de bien saisir. Voulez-vous dire que c'est ce genre de méthode qui cause problème ?
    void Videotheque::ajouteCoffret(Coffret coffret)
    {
    tableauCoffret_[i]=coffret;
    }

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par mynoud Voir le message
    Bonjour,
    Merci de votre réponse, je ne suis pas certain de bien saisir. Voulez-vous dire que c'est ce genre de méthode qui cause problème ?
    void Videotheque::ajouteCoffret(Coffret coffret)
    {
    tableauCoffret_[i]=coffret;
    }
    Effectivement, soit vous devez définir un constructeur par copie, soit vous devez l'alloué dynamiquement puis le passer par référence.

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Un bon réflexe à avoir est de se poser systématiquement la question, pour chaque classe, de ce qui se passe si on tente de copier une instance. Généralement, la réponse entre dans l'une de ces 3 catégories :
    • Mais, ça n'a pas de sens de copier une instance ! (ou la version moins forte : Mais, je n'ai jamais prévu qu'une instance puisse être copiée). Dans ce cas, il ne coûte pas grand chose de rencre la classe non copiable. http://cpp.developpez.com/faq/cpp/?p...iables_syntaxe
    • On peut très bien copier cette classe, et le constructeur de copie par défaut ainsi que l'opérateur= par défaut font très bien ce qu'il faut pour ça.
    • On peut très bien copier cette classe, mais le constructeur de copie par défaut et l'opérateur= par défaut ne font pas ce qu'il faut (ce qui arrive parce que la classe gère manuellement des ressources), et il faut donc que je les redéfinisse.


    Le troisième cas ne devrait vraiment pas apparaître souvent dans du code C++ moderne, puisque l'on ne gère pas les ressources manuellement, mais à l'aide de classes faites pour ça. Ainsi, dans ton code, tableauCoffret_ pourrait avantageusement être déclaré de type std::vector<Coffret>. Tu y gagnes :
    - Plus besoin d'appeler delete
    - Tu es dans le second cas, au lieu du troisième
    - Tu peux changer la taille de ton tableau dynamiquement si tu le désires
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. fuite de mémoire ?
    Par salseropom dans le forum C
    Réponses: 2
    Dernier message: 12/01/2006, 16h19
  2. Réponses: 1
    Dernier message: 02/12/2005, 14h18
  3. fuite de mémoire
    Par mamag dans le forum MFC
    Réponses: 17
    Dernier message: 19/08/2005, 10h42
  4. Fuite de mémoire en utilisant le template list
    Par schtroumpf_farceur dans le forum Langage
    Réponses: 9
    Dernier message: 18/07/2005, 20h44
  5. Réponses: 8
    Dernier message: 17/10/2002, 12h52

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