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

XML Discussion :

Problèmes destructeurs + "arbre" de vecteurs


Sujet :

XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 99
    Par défaut Problèmes destructeurs + "arbre" de vecteurs
    Bonjour!

    Ceci est mon tout premier message alors autant me présenter un peu: je suis étudiant en informatique pour les sciences, actuellement en stage de fin d'études. L'informatique pour les sciences est un master pour les personnes issuent d'autres filières scientifiques que l'informatique pure, on peut donc considérer que je suis débutant.

    L'université est très versée dans le Java, mais pour mon stage j'ai quand même dû apprendre le C/C++, vraiment sur le tas. Ce qui explique que je galère un peu.

    Voici mon problème:
    J'ai un arbre constitué de noeuds (classe Noeud). Les noeuds sont spécialisés à chaque étage: Arbre(racine) -> Type -> SousType -> Objet, tout ça pour coller au mieux à la structure du logiciel dont je programme une extension, tout en bénéficiant de la définition récursive de l'arbre.

    Chaque Noeud contient un pointeur vers le pere, et un vecteur de pointeurs vers les noeuds fils.
    La classe Objet est un peu particulière car elle contient un pointeur sur de la mémoire allouée par calloc. C'est une restriction imposée par l'API de l'hote.
    Pour stocker les pointeurs sur les fils (obtenus par "new ...") je suis obligé de les upcaster en Noeuds car le vecteur est déclaré comme un conteneur de Noeuds.

    L'arbre se construit sans mal, et j'ai même une belle sortie XML de mes données. Cependant, la destruction se passe très mal, faisant planter le greffon et l'hote.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //creation de l'arbre:
    Arbre *ar= new Arbre(...); //les constructeurs s'appellent en cascade 
    //en même temps que les données de l'hôte sont parcourues
    //destruction de l'arbre:
    delete ar;
    J'ai tenté de me reposer sur les destructeurs par défaut, tout en soupçonnant que le calloc() poserait problème. Ca ne marche pas de toutes façons.
    J'ai donc envisagé un destructeur virtuel dans Noeuds

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    virtual ~Noeud()
    {
      for(int i = 0; i < numFils; i++)
      {
        delete fils[i]; // vector<Noeud*> fils;
      }
    }
    Mais ça ne marche pas mieux. J'ai soupçonné devoir downcaster mes Noeud* (ceux du vecteur) dans leurs types réels pour pouvoir les supprimer. J'ai pas trouvé d'autre moyen que de déplacer le code ci-dessus dans les classes dérivées (c'est pas avantageux). Pour la classe Arbre ça donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ~Arbre()
    {
    	//fputs("Execution destructeur Arbre\n", debug);
    	for(int i = 0; i < numFils; i++)
    	{
    		delete (Type*)fils[i];
    	}
    	system("pause"); //pour contrôler où en est le code
    }
    ça ça se passe bien, j'ai une invite de commande qui apparait me demandant de presser une touche pour continuer, mais après avoir pressé une touche ça crashe! Il n'y même pas d'appel du destructeur ~Noeud!

    Je suis coincé! Je ne vois plus par quel bout attaquer le problème! Ce qui devait être une tâche à priori triviale (a vue de nez), s'avère être un gros calvaire:
    -ma mémoire ne se libère pas!
    -si j'enlève la commande "delete ar;" ça ne plante plus, mais une seconde execution fait planter l'hote, normal.
    -j'ai déjà trop passé de temps sur ce problème!

    Ma question est donc, sachant tout cela: quel est le moyen qui convient le mieux pour libérer la mémoire allouée à cet arbre?

    J'espère que vous pourrez m'aider!

    merci!
    mango

  2. #2
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 46
    Par défaut
    Bonjour,

    Quel IDE utilises-tu? n'as-tu pas la possibilité de savoir exactement où ça plante? Est-ce que Arbre est une classe fille?

  3. #3
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Avec un arbre vide, ça crashe aussi ?
    Pas besoin de down/upcaster dans tes delete si tes destructeurs sont virtuels.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 99
    Par défaut
    Ouah! ça fait super plaisir d'avoir un peu de support! Grand merci!

    J'utilise Code::Blocks, mais le déboggueur (gdb ou cdb) refuse d'entrer dans le programme hote, (je pense que le fait que celui-ci ne soit pas compilé avec les intructions de déboggage y est pour quelque chose, et c'est un logiciel propriétaire dont je n'ai pas le code ^^).

    (Héhé, je me suis gratté la tête un instant en me demandant comment faire un arbre vide... me faut un café)
    Alors, j'ai donc fait un constructeur vide qui me crée juste un Noeud Arbre (oui, Arbre est dérivée de Noeud), et même affaire, crash après le system("pause");

    C'est noté pour les cast sur les delete, ça n'a pas posé de pb au compilateur! C'est bon a prendre ^^

    Hum, j'ai un diagramme de classes à jour si vous voulez avoir quelque chose de plus visuel! Suffit de demander!

    Je suis sûr que ça ne doit pas être sorcier, mais là, je trouve pas!


    Mango

  5. #5
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Si tu as du code, tu peux débugger avec les instructions de débuggage, et comme c'est toi qui codes...
    Et si un arbre vide crashe le programme, vérifie bien ce que tu fais.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 99
    Par défaut
    okay, je vais tout remettre à plat, je vous tiens au courant!
    En tout cas, ça m'a fait un petit break!

    Merci
    Mango

  7. #7
    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 : 51
    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
    Deux idées :

    1/ Confusion calloc/new :

    Si tu as alloué avec calloc, tu dois libérer avec free (à vérifier, je ne connais pas le C), si tu as alloué avec new, tu dois libérer avec delete. Mélanger les deux est une erreur.

    Pas ailleurs, calloc ne fais qu'allouer de la mémoire, mais n'appelle pas les constructeurs. Donc, en général, quand on doit utilisr ce genre de fonctions en C++, le cycle est le suivant :
    - Allocation mémoire avec calloc
    - Création de l'objet avec placement new
    - Appel explicite au destructeur (pas delete)
    - Libération mémoire

    2/ Le destructeur de toutes tes classes de base polymorphiques est-il bien virtuel ?
    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.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Wamp] Problème d'insertion avec quote d'un formulaire
    Par cyberdevelopment dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 20/08/2006, 18h55
  2. [SQL-Server] Problèmes de guillemets et quotes dans un INSERT
    Par gregb34 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 05/05/2006, 09h40

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