BifaceMcLeOD The HighGlandeur | Evadream -jbd- a écrit a écrit :
Bonjour, me revoilà car j'ai un problème de compréhension :
Prenons cette fonction :
Code :
- void addql(data** head, data* element){
- data* courant = *head;
- if( *head == NULL ){
- *head = createElement(0,0,0);
- *head = element;
- }
- else{
- while(courant->next != NULL)
- courant = courant->next;
-
- courant->next = element;
-
- }
- //free(courant);
- }
|
Si j'ajoute 1000 élements à ma liste, je vais créer 1000 fois un pointeur data* courant, il ne faut pas que je le désalloue ? Si je fais un free sur ce pointeur, je désalloue la mémoire pointée, donc *head c'est ca ?
Je viens de me rendre compte que ce que je viens de dire est idiot car dès que je sors de ma fonction, courant n'existe plus comme tout autre variable local à cette fonction ? Il ne faut donc pas désalloué courant sous peine de perdre *head, c'est ca ?
Je m'inquiete, je dois avoir un réel problème de conception de mon programme, car dès que je dépasse une certaine valeur de taille de données, mon processus est tué par le sytème. Je sais que mon algorithme est vraiment naif, mais c'est la première fois que je travaille avec des entités aussi "grosses, je n'ai donc jamais été confronté à ce genre de problèmes =)
Merci d'avance à tous !
A+
|
Attends, attends, j'ai peut-être été trop vite dans mes réponses hier.
Dans le principe, définir une fonction qui rassemble toutes les instructions qui initialisent un noeud, c'est bien. Maintenant, si la question, c'est "est-ce qu'appeler cette fonction createElement comme c'est fait ici, c'est approprié ?", la réponse est différente. Et je crains que ce soit non. Je détaille.
if( *head == NULL ){
Ici on suppose que head est un pointeur valide. Admettons. Si ce pointeur est NULL, on rentre dans le bloc "then" du "if". OK.
*head = createElement(0,0,0);
Par l'appel à createElement, on alloue de la mémoire et on l'initialise. Puis on afecte l'adresse de cette zone mémoire à la zone mémoire pointée par head, qui contient elle-même l'adresse d'une autre zone mémoire (double pointeur). OK.
*head = element;
On affecte l'adresse mémoire contenu dans element à *head. La précédente adresse que contenait *head est donc perdue, puisqu'on ne l'a pas gardée ailleurs ==> fuite mémoire. En l'occurrence, l'appel à createElement est ici inutile.
Maintenant, voyons ta question.
Si j'ajoute 1000 élements à ma liste, je vais créer 1000 fois un pointeur data* courant, il ne faut pas que je le désalloue ? Si je fais un free sur ce pointeur, je désalloue la mémoire pointée, donc *head c'est ca ?
Oui, dans le principe : si tu alloues, il y a un jour où tu devras désallouer. Mais ici, addql ne devrait pas avoir à faire d'allocation mémoire, car cette fonction suppose que tout est déjà alloué comme il faut : en particulier "element" qui est un pointeur valide sur une structure de type "data" .
Attention, par définition, un "pointeur courant" est un pointeur qui se balade sur des noeuds existants. On ne fait pas d'allocation directe dans ce pointeur, et donc on ne fait pas de désallocation dessus. Il est juste un moyen d'accéder aux différents élements d'une liste (ou d'une structure plus complexe).
Par contre, il est possible que tu doives faire des allocations dans des zones mémoires pointées par ton pointeur baladeur. Dans ce cas, ce sont tes noeuds qui reçoivent les adresses des nouvelles zones mémoires, pas ton pointeur baladeur lui-même.
Ici, si tu retires l'appel à "createElement", ta fonction "addql" me paraîtra correcte. Message édité par BifaceMcLeOD le 13-11-2002 à 10:31:54
|