Free et structures ... - C - Programmation
Marsh Posté le 20-09-2005 à 15:34:25
ca doit dépendre des compilateurs mais normalement oui il faut le faire
Marsh Posté le 20-09-2005 à 16:22:51
in_your_phion a écrit : Je voudrais savoir si quand j'ai un pointeur de structure, et que je le désalloue, dois-je désallouer aussi tout ce qu'il y a dans ma structure avant (si par exemple ma structure contient un tableau alloué) ? |
#2. Le principe est simple. Pour chaque malloc()/realloc()/calloc(), il doit y avoir un free.
Et n'oublie pas de tester les valeurs retournées par malloc() avant de les utiliser...
Marsh Posté le 20-09-2005 à 17:30:23
Emmanuel Delahaye a écrit : #2. Le principe est simple. Pour chaque malloc()/realloc()/calloc(), il doit y avoir un free. |
ok merci les gars ... bon ben c'est quand meme ennuyeux de devoir faire tout un tas de desallocations à chaque fois.
Juste une autre p'tite question rapport au free ... Si j'ai une fonction qui fait un free, dois-je obligatoirement passer en argument un pointeur ?
par ex
si j'ai :
int **my_array;
est ce que ma fonction free doit etre :
1)
void nuke_array (int **array) {
free(*array);
*array = NULL;
}
//et l'appel
nuke_array(my_array);
2) ou alors:
void nuke_array (int ***array) {
free(**array);
**array=NULL;
}
//appel
nuke_array(&my_array);
merci ..
Marsh Posté le 20-09-2005 à 17:56:40
Si j'ai bien compris, array est un tableau à deux dimensions dont chaque dimension est allouée avec malloc().
Du coup, j'aurais plutôt voté un truc du genre :
Code :
|
Que tu appelles avec un : "nuke_array(&ton_tableau, nombre_de_lignes);"
Mais il faudrait que tu nous montres comment tu définis array pour en être sûr.
Marsh Posté le 20-09-2005 à 18:02:52
Elmoricq a écrit : Mais il faudrait que tu nous montres comment tu définis array pour en être sûr. |
En fait c'est un faux tableau, j'utilise quasiment jamais des vrais tablos 2d :
int **array = (int*)malloc(sizeof(int)*TAILLE_X*TAILLE_Y);
En fait free c'est une opération de modification ? si c'est ça je dois passer un pointeur alors (donc un *** dans mon cas), nan ?
Marsh Posté le 20-09-2005 à 18:07:46
Euh, tu es au courant ton tableau est à une seule dimension, là, et qu'il te suffit de faire :
Code :
|
Et, du coup, free(array) suffit largement.
EDIT :
Citation : En fait free c'est une opération de modification ? si c'est ça je dois passer un pointeur alors (donc un *** dans mon cas), nan ? |
Ce n'est pas pour free() qu'on doit passer l'adresse, c'est pour le array = NULL
Citation : ps : que fait le test |
Pareil que "if ( *array != NULL )"
Marsh Posté le 20-09-2005 à 18:14:15
Elmoricq a écrit : Euh, tu es au courant ton tableau est à une seule dimension, là, et qu'il te suffit de faire :
|
ok merci bien .. j'ai enlevé ce dernier commentaire car j'ai compris avec ta réponse entre temps. Euh, non enfin mon tableau set à deux dimensions .. c'est juste que c'est de mémoire que je me rappelle ce probleme, j'ai pas vraiemtn d'exemple concret. Mais par rapport a ce que tu dis : si je fais juste un free ce n'est pas considéré comme une modif ? et l'assignation NULL oui ?
Marsh Posté le 20-09-2005 à 18:18:27
free() n'affecte pas la variable, il permet simplement de libérer la mémoire réservée pointée par la variable (mais il ne la rend pas au système, il ne fait que la rendre au programme lui-même).
La mémoire pointée par la variable peut donc potentiellement être écrasée par n'importe quoi dans ton programme, puisque plus rien ne la réserve.
Par conséquent, on prend l'habitude d'affecter NULL à la variable ainsi libérée, histoire d'éviter les potentiels comportements indéfinis si par malheur la variable venait à être utilisée après un free() (comportement indéfini, l'un des bugs les plus difficiles à détecter )
En revanche, affecter une valeur à une variable, fut-ce un pointeur, est évidemment une modification.
Marsh Posté le 20-09-2005 à 19:02:08
in_your_phion a écrit : ok merci les gars ... bon ben c'est quand meme ennuyeux de devoir faire tout un tas de desallocations à chaque fois. |
C'est pour ça qu'en principe, on utilise des constructeurs / destructeurs qui font le boulot en silence...
http://mapage.noos.fr/emdel/tad.htm
Citation : |
En fait, tu veux savoir si on doit mettre le pointeur à NULL et comment on fait...
Il est effectivement recommandé de remettre un pointeur qui ne pointe plus sur un bloc valide (donc après un free) à NULL.
J'ai l'habitude d'écrire ceci :
free (p), p = NULL;
Si on utilise une fonction, on peut faire de différentes façons :
|
Avec
|
Marsh Posté le 20-09-2005 à 19:03:51
Elmoricq a écrit :
|
Héhé ! Je vois que je commence à faire des adeptes !
Marsh Posté le 20-09-2005 à 19:57:37
in_your_phion a écrit : |
Welcome to the C world.
Marsh Posté le 20-09-2005 à 22:59:38
Emmanuel Delahaye a écrit : Héhé ! Je vois que je commence à faire des adeptes ! |
J'initialisais toujours à NULL (on apprend vite à le faire après de longues séances de debug ), mais sur deux lignes, je ne connaissais pas cette syntaxe avec la virgule avant.
Ca donne l'impression d'une seule action, donc c'est plus lisible, alors j'ai effectivement adopté la syntaxe.
Marsh Posté le 21-09-2005 à 08:38:28
Elmoricq a écrit : JCa donne l'impression d'une seule action, donc c'est plus lisible. |
Exactement. Autre avantage, GNUIndent laisse la ligne entière, ce qui renforce l'impression de cohésion.
Marsh Posté le 21-09-2005 à 09:47:38
Elmoricq a écrit : J'initialisais toujours à NULL (on apprend vite à le faire après de longues séances de debug ), mais sur deux lignes, je ne connaissais pas cette syntaxe avec la virgule avant. |
Pourtant on utilise beaucoup la virgule (opérateur séquentiel) en C comme ici
=> "appel_fonction(a, b, c)"
ou bien ici
=> "int a, b, c".
Tu peux même écrire des trucs inutiles style
=> "a=(5, 6, 7 + 3)"
Marsh Posté le 21-09-2005 à 09:54:36
Sve@r a écrit : Tu peux même écrire des trucs inutiles style |
tiens, j'avais jamais vu.
comment est résolue l'expression ?
Marsh Posté le 21-09-2005 à 09:59:19
blackgoddess a écrit : tiens, j'avais jamais vu. |
Ben déjà j'ai mis des parenthèses parce que je ne connais pas les priorités par coeur (priorité du "=" par rapport à la virgule).
Donc, l'expression évalue la parenthèse en premier et l'expression "7 + 3" est la dernière à en ressortir (opérateur "séquentiel" )
Cette expression est ensuite stockée dans "a" (opérateur d'affectation) => a vaut 10
Marsh Posté le 21-09-2005 à 09:59:28
J'imagine que a vaudra successivement 5, 6 puis 7+3.
Ce qui est inutile, comme l'a dit Sve@r
EDIT : grillé
Marsh Posté le 20-09-2005 à 15:32:30
Salut,
Je voudrais savoir si quand j'ai un pointeur de structure, et que je le désalloue, dois-je désallouer aussi tout ce qu'il y a dans ma structure avant (si par exemple ma structure contient un tableau alloué) ?
par exe:
typedef struct {
double *nombredeneuronesperdus;
}spliff;
/* et la par exmple j'alloue ma structure spliff bob_marley */
spliff *bob_marley = (spliff*)malloc(sizeof(spliff));
/** Et puis j'alloue mon tableau de double */
bob_marley->nombredeneuronesperdus = (double*)malloc(sizeof(double)*10000000000000000000000);
...
Je voudrais savoir si, lors de la libération :
1) Est ce que
free(bob_marley);
suffit ?
2) Ou bien dois-je nécéssairement faire :
free(bob_marley->nombredeneuronesperdus);
//et ensuite
free(bob_marley);
??
merci par avance
Message édité par in_your_phion le 20-09-2005 à 15:34:59