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 :

Libération de mémoire


Sujet :

C++

  1. #1
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177
    Par défaut Libération de mémoire
    Bonjour,

    J'ai un pb qui survient lors de la libération de mémoire
    allouée pour les objets d'une classe, mais je n'arrive absolument pas à
    savoir pourquoi, (lorsque je quitte l'appli un message d'erreur
    de Windows s'affiche).

    Le code étant extrêmement long et compliqué je vais simplifier.
    La classe en question alloue un tableau d'objets lors de sa
    création:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    MaClasse(int taille) 
      {
        pObj = new Obj[taille];
        ...
      }
    et libère la mémoire allouée lors de sa destruction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ~MaClasse(){delete[] pObj;}
    Quelque part dans une autre classe 2 objets MaClasse sont créés:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MaClasse *p1 = new Maclasse(50);
    MaClasse *p2 = new Maclasse(50);
    et sont détruits dans le destructeur de cette même autre classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    delete p1;
    delete p2;
    Le pb apparement vient qu'il y a 2 instanciations/libérations.
    Si je n'instancie qu'un seul objet je n'ai pas d'erreur
    lors de la désallocation.

    Est ce que quelqu'un aurait eu ce genre de pb ou aurait
    une idée ?


    D'avance merci.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Ta classe gère la durée de vie d'une ressource, tu as donc d'autres critères à vérifier:
    • soit elle doit être explicitement non-copiable et non-assignable (constructeur de copie et opérateur d'affectation déclarés privés et non-définis),
    • soit elle est copiable, et doit donc avoir un constructeur de copie (et un opérateur d'affectation aussi, si elle est assignable) clairement défini. Si elle possède aussi un opérateur d'affectation, je conseille l'idiome copy-and-swap.

    De plus, pour être parfaitement exception-safe, ta classe ne doit gérer "elle-même" la durée de vie que d'une seule ressource. (en gros, un seul new dans le corps du constructeur, un seul delete dans le corps du destructeur).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Le code que tu montres n'as pas de raison à priori de ne pas fonctionner. Donc, je pense comme Medinoc: quelque part tu dois avoir une copie de ta variable et ceci n'est pas gérer correctement.

  4. #4
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177
    Par défaut
    Oui je crois qu'en effet la classe (celle qui alloue un tableau) n'est pas en cause.
    J'ai déjà effectué un 1er traçage mais je n'ai rien remarqué de suspect.
    C'est vrai que le code est long et complexe, je pense qu'il faut donc que je surveille le code pas à pas mais bon, pas évident...

    Si quelqu'un à une idée/intuition qu'il n'hésite pas.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Ben l'idée, c'est ce qu'à dit Médinoc au début: l'opérateur = et le constructeur par copie sont-ils gérés? Probablement non, et l'erreur est ici.

  6. #6
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177
    Par défaut
    L'opérateur = et le constructeur par copie ne sont effectivement pas
    gérés, mais le truc c'est qu'ils ne sont pas utilisés dans mon code (enfin je crois).
    Tout se déroule (en gros) comme dans l'exemple que j'ai donné plus haut, aussi je ne pense pas que l'opérateur = et le constructeur par copie interviennent dans ce genre de code (mais je peux me tromper )

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Pour être absolument sûr qu'ils ne sont pas utilisés, rends ta classe non-copiable et non-assignable, en les déclarant private sans les définir.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par tintin72 Voir le message
    enfin je crois
    Probablement à un endroit dont tu ne te doutes même pas. Comme dit Médinoc, pour en être sûr déclare les en private et compile. Tu le verras tout de suite.

  9. #9
    Membre éclairé
    Avatar de buggen25
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    554
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Août 2008
    Messages : 554
    Points : 709
    Points
    709
    Par défaut
    Salut
    ~MaClasse(){delete[] pObj;}
    Je pense qu'il faudrait ajouter une fonction membre qui supprime l'objet créer par un pointeur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void CMaClasse::Clear()
    {
        if(pObj != NULL) // tester si le pointeur n'est pas NULL
        delete[] pObj;
    }
    On detruit l'objet pObj
    Ensuite on detruit l'instance de CMaClass
    Cordialement
    If you type Google into Google, you Can break the internet" - The IT Crowd

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par buggen25 Voir le message
    Salut
    ~MaClasse(){delete[] pObj;}
    Je pense qu'il faudrait ajouter une fonction membre qui supprime l'objet créer par un pointeur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void CMaClasse::Clear()
    {
        if(pObj != NULL) // tester si le pointeur n'est pas NULL
        delete[] pObj;
    }
    On detruit l'objet pObj
    Ensuite on detruit l'instance de CMaClass
    Cordialement
    1. Ça ne sert à rien ici, ça n'est pas le problème.
    2. Inutile de tester NULL avant, delete[] NULL est garanti ne rien faire.
    3. Par contre, tu oublies de mettre le pointeur à NULL, ce qui fait qu'il risque d'être deleté deux fois.

    Ce n'est pas la peine de venir aider si c'est pour donner du code dangereux...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177
    Par défaut
    Pour être absolument sûr qu'ils ne sont pas utilisés, rends ta classe non-copiable et non-assignable, en les déclarant private sans les définir.
    Pourrais tu me dire comment faire pour les déclarer private sans les définir, (un petit exemple).
    J'avoue que je nage un peu là.

  12. #12
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MaClasse
    {
      MaClasse(Maclasse const &);
      MaClasse& operator=(MaClasse const &);
    };
     
    // Ou alors
     
    class MaClasse : boost::noncopyable
    {
    };
    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.

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class MaClasse
    {
    	...
    	...
    private:
    	MaClasse(MaClasse const &);
    	MaClasse & operator= (MaClasse const &);
    };
    Et rien d'autre.
    Ils sont déclarés, privés, mais définis nulle part. Donc, si quelque chose tente de les utiliser, il y aura une erreur de compilation ou d'édition de liens (selon qu'on tente de l'utiliser depuis la classe elle-même ou depuis l'extérieur).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Edit : Grillé, grillé et regrillé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    class A
    {
    private:
         A(const A&);    
         A& operator=(const A&);
    };
    Edit2 :

    Pourquoi avez-vous écrit tous les deux : MaClasse(MaClasse const &) ?
    Y a t-il une différence avec l'usuel: MaClasse(const MaClasse&) ?

  15. #15
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177
    Par défaut
    Merci pour vos réponses rapides
    Malheureusement ça compile sans pb
    Aucun warning, rien. J'ai bien peur d'avoir affaire
    à une erreur plutot vicieuse.
    Bon j'y retourne.

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Pourquoi avez-vous écrit tous les deux : MaClasse(MaClasse const &) ?
    Y a t-il une différence avec l'usuel: MaClasse(const MaClasse&) ?
    Aucune différence, mais pour le compilo, c'est le X const & qui est l'usuel : Le const X & est un cas particulier autorisé pour le type le plus à gauche, mais en temps normal, le const est à droite du type :
    X const * const * pcpcX;
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par tintin72 Voir le message
    Malheureusement ça compile sans pb
    Aucun warning, rien.
    Ca n'empêche pas de gérer correctement ton pointeur !
    Citation Envoyé par tintin72 Voir le message
    J'ai bien peur d'avoir affaire
    à une erreur plutot vicieuse.
    Alors c'est peut dû au fait que tes objets sont détruits 2 fois pour une autre raison : tu fais explicitement 2 fois un delete sur la même adresse. La seconde hypothèse, c'est le charcutage mémoire! Enfin, à ce stade, il faut un peu plus de code pour t'apporter de l'aide.
    Bon courage.

  18. #18
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177
    Par défaut
    La seconde hypothèse, c'est le charcutage mémoire!
    Qu'est ce que le "charcutage mémoire" exactement ?

  19. #19
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Pourquoi avez-vous écrit tous les deux : MaClasse(MaClasse const &) ?
    Y a t-il une différence avec l'usuel: MaClasse(const MaClasse&) ?
    Parce que pour nous, c'est ça l'écriture usuelle ?
    Il n'y a pas de différence en l'occurrence. La règle est que const s'applique à ce qui est placé avant lui, sauf s'il apparait en début, auquel cas il s'applique à ce qui est place derrière. Cette règle est surtout utile dans des écritures genre int const * (pointeur sur entier constant ou pointeur constant sur entier ?).

    Écrire int const i = 42; au lieu de const int i = 42; permet de se placer dans le cas général, et non dans un cas particulier. C'est une question d'habitude.
    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.

  20. #20
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par tintin72 Voir le message
    Qu'est ce que le "charcutage mémoire" exactement ?
    Tu as alloué les octets 5 à 10 et tu écris sur l'octet 11 ou 4. Bref, là où tu n'as pas le droit.

Discussions similaires

  1. Libération de mémoire non réservée (operator=)
    Par 84mickael dans le forum C++
    Réponses: 7
    Dernier message: 27/05/2006, 13h30
  2. Problème libération de mémoire?
    Par Bartuk dans le forum C
    Réponses: 7
    Dernier message: 28/12/2005, 17h20
  3. Libération de mémoire
    Par petitcoucou31 dans le forum Langage
    Réponses: 1
    Dernier message: 16/09/2005, 14h10
  4. [Debutant(e)]problème de libération de mémoire
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 10/02/2005, 17h38
  5. Réponses: 25
    Dernier message: 16/07/2003, 20h41

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