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.
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.
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 donc envisagé un destructeur virtuel dans Noeuds
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 virtual ~Noeud() { for(int i = 0; i < numFils; i++) { delete fils[i]; // vector<Noeud*> fils; } }
ç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!
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 }
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
Partager