|
|
|
|
Bonjour,
J'ai cherche sur le forum les réponses à mes questions, mais certaines restent sans réponses ou un peu floues... :(
Je vous explique mon problème:
Je dois faire un projet un C, dans lequel j'ai décidé d'utiliser une structure d'arbre pour représenter des mots/phrases.
Voici la structure de mes noeuds:
typedef struct t_Noeud t_Noeud;
struct t_Noeud{
char C; //Caractère du noeud
unsigned int Nb_fils;
t_Noeud* *Fils; //Tableau dynamique de liens vers la suite de l'arbre.
};
void Initialiser_Noeud(t_Noeud *i_Ptr_noeud, char i_Car)
{
i_Ptr_noeud->C = i_Car;
i_Ptr_noeud->Nb_fils = 0;
i_Ptr_noeud->Fils = NULL;
}
void Ajouter_nouvelle_chaine(t_Noeud *i_Ptr_noeud, char i_Car)
{
size_t Taille_alloc_fils = i_Ptr_noeud->Nb_fils + 1;
size_t Taille_alloc_noeud = sizeof(t_Noeud);
/*Agrandir tableau de "fils de 1 case
*fonctionne comme malloc(Taille_alloc_fils) si i_Ptr_noeud->Fils == NULL
*/
i_Ptr_noeud->Fils = realloc(i_Ptr_noeud->Fils,Taille_alloc_fils);
//Ajouter un nouveau noeud en dernière position
i_Ptr_noeud->Fils[i_Ptr_noeud->Nb_fils] = malloc(Taille_alloc_noeud);
//Initialisation du nouveau noeud.
Initialiser_Noeud(i_Ptr_noeud->Fils[i_Ptr_noeud->Nb_fils],i_Car);
//Le nombre de fils est incrémenté.
i_Ptr_noeud->Nb_fils++;
}
void main()
{
//Début du programme
t_Noeud *Racine = malloc(sizeof(t_Noeud)), *P = NULL;
Initialiser_Noeud(Racine,'@');
//Corps du programme
//...
//...
//Fin du programme
free(Racine);
}
void Liberer_noeud(t_Noeud *i_Ptr_Noeud);
Configuration: Windows XP Firefox 2.0.0.12
Bonjour
size_t Taille_alloc_fils = i_Ptr_noeud->Nb_fils + 1; ce ne serait pas plutôt : size_t Taille_alloc_fils = (i_Ptr_noeud->Nb_fils + 1) * sizeof(unsigned int); Question 1 : Non, la signature de la fonction n'a pas à changer. Elle a toujours besoind des mêmes paramètres en entrée, ni plus ni moins et elle reste de type void. Question 2 : Tu passes une copie d'un pointeur. Mais ce que tu modifies dans ta fonction, ce n'est pas le pointeur, c'est la variable pointée. Or un pointeur et sa copie contiennent l'adresse de la même zone mémoire : toute modification de la zone mémoire pointée par l'un modifie la zone mémoire pointée par l'autre, puisque c'est la même ! Le problème aurait été tout différent si dans ta fonction tu faisais un i_Ptr_noeud=malloc(..) ou realloc(..) Question 3 : un Free à la racine de l'arbre ne suffit pas : la fonction free ne connaît rien de ta structure et est donc incapable de parcourir tous les noeuds. Tu es effectivement obligé de les libérer toi-même. Une fonction récursive, qui bien sûr libère les fils avant le noeud parent, est le meilleur moyen de le faire. La signature que tu proposes me semble tout à fait convenir : là encore, tu ne cherches pas à récupérer une valeur modifiée du pointeur (tu en ferais quoi ?) |
Bonjour le père, et merci pour tes réponses.
Remarque préliminaire : size_t Taille_alloc_fils = i_Ptr_noeud->Nb_fils + 1; ce ne serait pas plutôt : size_t Taille_alloc_fils = (i_Ptr_noeud->Nb_fils + 1) * sizeof(unsigned int); Merci je vois que j'ai juste mis le nombre de case mémoire que je veux réserver mais pas leur taille... Je fais un tableau de pointeur en gros, donc size_t Taille_alloc_fils = (i_Ptr_noeud->Nb_fils + 1) * sizeof(unsigned int); doit être size_t Taille_alloc_fils = (i_Ptr_noeud->Nb_fils + 1) * sizeof(t_Noeud*); non? Ou est-ce peut être la même chose? Question 1 : Non, la signature de la fonction n'a pas à changer. Elle a toujours besoin des mêmes paramètres en entrée, ni plus ni moins et elle reste de type void. Oui je comprends maintenant, j'ai confondu le pointeur que je passe en paramètre et mon tableau de pointeur sur la suite de l'arbre. Donc si j'ai compris, puisque je modifie le noeud repéré les paramètres sont bons. Question3: [...] En fait, je pensais que si je passais par recopie le pointeur, la libération n'aurait pas eu lieu... Une dernière question concernant ma fonction de libération mémoire: Après la libération d'un noeud, est-il conseillé d'affecter le pointeur à null? Voila la fonction en question:
void Liberer_noeud(t_Noeud *i_Ptr_Noeud)
{
unsigned short i;
//libération des noeuds fils
for ( i = 0 ; i < i_Ptr_Noeud->Nb_fils ; i++ )
{
Liberer_noeud(i_Ptr_Noeud->Fils[i]);
i_Ptr_Noeud->Fils[i] = NULL;
}
free(i_Ptr_Noeud);
}
|
Size_t Taille_alloc_fils = (i_Ptr_noeud->Nb_fils + 1) * sizeof(t_Noeud*);
|