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 :

Arbres binaires, destructeurs récalcitrant, auto_ptr déroutant les constructeurs.


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut Arbres binaires, destructeurs récalcitrant, auto_ptr déroutant les constructeurs.
    Bonjour,

    j'avais un problème de fuites de mémoire dans un programme de calcul symbolique qui représente les fonctions sous forme d'arbre binaire.

    Typiquement des que je mettais un destructeurs classique qui tue les fils, ça me donnait des segfaults de partout.

    Les segfaults se produisent lors de la destruction d'un nœud ayant des successeurs.

    J'ai donc décidé d'essayer de remplacer mes pointeurs par des auto_ptr, qui je crois sont censés aider dans la gestion des destructions des objets dynamiques.

    Et là étrange problème, mes constructeurs ne marchent plus,par exemple pour créer une fonction constante, j'ai la classe number, si dans un programme j'écris

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    number One=number(1);
    le compilateur me dit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    erreur, no matching function to call number:number(number).
    les candidats sont: 
    number.h(l56)         number:number(double)
    number.h(l41)         number:number(number&)
    Alors d'une part c'est étrange car je n'ai aucune idée de la manière dont mon code s'est mis à considérer les doubles comme des "numbers", et sont deuxième candidat n'est autre que la ligne de déclaration de la classe number

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    class number : public noeud {
    ....
    En fichier joint, il y a les deux versions de mon code

    src_std_ptr.tar.bz2 est la version qui compile, tourne, mais a d'énormes fuites (et dans laquelle je n'arrive pas à définir de destructeur)

    src_std_auto_ptr.tar.bz2 est la version avec des auto_ptr, qui confond les doubles et les objets de mes classes.

    Si quelqu'un sait d'où vient l'un ou l'autre des problèmes, je suis preneur, car c'est assez frustrant d'avoir un code dans lequel on n'arrive pas à mettre les destructeurs dans le premiers cas, et dans le deuxième qu'on n'arrive pas à tester.

    Merci bien.

    --
    Z.
    Fichiers attachés Fichiers attachés

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    Euh, non, pas trop:
    Le premier candidat est le constructeur de number à partir de double, et le second est un constructeur de copie de number.

    Aucun des deux n'est valides car il faut un constructeur de copie prenant en paramètre une référence const.

    Ce problème vient du fait que le C++ refuse les références non-const de temporaires non-nommés.
    Et ta ligne number One = number(1); crée un temporaire non-nommé et tente d'appeler le constructeur de copie dessus. Pour ne pas faire de copie, il suffirait de faire number One(1);
    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
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    Mmh intéressant, ça règle en effet le cas du auto_ptr, merci beaucoup.

    Il reste que je ne comrepnd pas pourquoi dans la version sans auto_ptr je pouvais écrire
    number One=number(1)

    Alors que maintenant je ne peux plus.

    Merci encore.

    --
    Z.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    Typiquement, les auto_ptr<> ont un constructeur de copie non-const (puisqu'ils ont une sémantique de transfert et non de copie). Ça peut être lié à ton problème...

    D'ailleurs, en regardant ton code, je me demande si auto_ptr est bien le meilleur type pour ce que tu cherches à faire...
    Notamment, ta fonction noeud::prec() supprimme le pointeur prec du noeud. Est-ce vraiment ce que tu veux faire ?
    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.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    D'ailleurs, en regardant ton code, je me demande si auto_ptr est bien le meilleur type pour ce que tu cherches à faire...
    Oui, pour ça je n'en sais rien, mais le truc et que je n'ai pas réussi à faire de destructeur viable avec les pointeurs normaux, donc j'essaye les auto_ptr pour limiter les fuites car elles atteignent un niveau impressionnant.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    Ça ne marchera pas.

    Si tu veux vraiment avoir des pointeurs avec des destructeurs, utilise la bibliothèque boost et ses shared_ptr<> (ou bien des intrusive_ptr<>) : Ce sont des pointeurs à comptage de références.
    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.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    noeud::prec() supprimme le pointeur prec du noeud
    Avec un
    je supprime un quelconque pointeur ?

    dans l'esprit de ce que je voulais faire c'était juste donner un moyen public d'accès en lecture au pointeur du noeud parent d'un noeud....

    Doit y avoir mille choses que je n'ai pas comprises....

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    Tu sembles surtout ne pas avoir bien compris le principe d'un auto_ptr<>.

    Si le constructeur de copie de auto_ptr<> n'est pas const, c'est pour une raison: Il modifie l'auto_ptr d'origine et le met à NULL.
    C'est pour ça qu'on appelle ça un transfert.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    auto_ptr< machin > a = new machin();
    auto_ptr< machin > b = a;
     
    //Maintenant, a est nul.
    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.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    ah oui d'accord, c'est en effet un peu gênant et je n'avais pas du tout vu venir ce problème...

    Et sur le destructeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    virtual  ~noeud(){
    delete suivant1;
    delete suivant2;
    }
    éventuellement avec un test pour la non nullité du pointeur (quoi que je ne suis pas certain qu'un delete NULL soit grave) qui fait planter dès qu'un noeud à des successeurs, ça viendrait du fait que parfois ça entraine plusieurs suppressions d'un même noeud ou celle d'un noeud ver slequel pointe encore quelquechose ?

    --
    Z.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    delete NULL est garanti ne rien faire.

    Mais oui, il y a de grande chances que les plantages viennent d'un double delete sur le même noeud, ou d'un pointeur oublié sur ces noeuds.
    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
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 409
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    Et aussi, il me semble qu'on ne delete pas sur un auto_ptr<> : Il s'en charge tout seul, c'est l'intéret...
    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.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    Oui, le delete c'est sur le version avec les braves vieux pointeurs standards, si j'ai essayé les auto_ptr, c'était dans l'espoir d'avoir un truc qui me fasse les delete tout seul et sans segfault, avec le désavantage d'avoir à changer pas mal de code pour avoir un résultat qui risque de ne rien régler du tout comme problème...

    --
    Z.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    Si tu prends la bibliothèque boost, tu pourras utiliser des shared_ptr<> qui feront le travail pour toi.
    Malheureusement, je n'y ai jamais touché, donc je ne sais pas l'installer. Mais tu dois pouvoir trouver ça sur le forum...
    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 averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    D'accord, merci bien.

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    Hmm en fait ave les shared_ptr, ça me fait exactement pareil qu'avec les pointeurs normaux avec destructeurs, glibc6 détecte un double free ou un truc du genre dès que j'utilise un truc qui utilise des nœuds intermédiaires...

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    Impossiible à moins que tu ne fasses toi-même un free() quelque part.
    Tu dois laisser les shared_ptr<> gérer entièrement la durée de vie des noeuds.
    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
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    Pourtant j'ai remplacé tous mes noeud* par des shared_ptr<> et j'ai viré tout ce qui ressemble à du free ou du delete...

    Enfin bon je regarderai ptet encore un peu par là...

    Grosso modo j'ai l'impression qu'il "n'aime pas" la surcharge des opérateurs pour mes noeuds...

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    Quels sont les opérateurs que tu as surchargés ?
    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.

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 20
    Par défaut
    J'ai surchargé - (unaire et binaire) + * et /, pour permettre de faire ces opérations sur des noeuds (qui sont en fait des fonctions à valeur réelle).

    J'ai aussi surchargé <<.

    --
    Z.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 409
    Par défaut
    Fais gaffe à bien opérer sur les noeuds et non sur les pointeurs...
    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.

Discussions similaires

  1. Questions diverses sur les Arbres binaires + insertion d'un fils
    Par beegees dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 18/03/2008, 01h21
  2. Demande sur les arbres binaire
    Par IDE dans le forum C++
    Réponses: 12
    Dernier message: 02/12/2007, 17h55
  3. Les arbres binaire en java
    Par vincem35 dans le forum Langage
    Réponses: 3
    Dernier message: 15/11/2007, 19h44
  4. Java et les arbres binaires
    Par Noutch dans le forum JBuilder
    Réponses: 1
    Dernier message: 17/08/2007, 14h25
  5. Le type Arbre binaire dans les bibliothèques standards ?
    Par sam69 dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 10/05/2006, 13h50

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