C Libérer la mémoire

Résolu/Fermé
Atropa Messages postés 1940 Date d'inscription mercredi 25 juin 2008 Statut Membre Dernière intervention 11 mai 2014 - 4 juin 2009 à 00:52
Atropa Messages postés 1940 Date d'inscription mercredi 25 juin 2008 Statut Membre Dernière intervention 11 mai 2014 - 5 juin 2009 à 04:08
Bonsoir,

J'apprend le C depuis quelques jours, et je me demandais l'utiliter de liberer la mémoire avec free pour les malloc avant de fermer le programme

le system d'exploitation ne le fera pas automatiquement?

à quoi sert le
return EXIT_SUCCESS;
dans le main?

et enfin est ce que ca pose probleme de fermer sont programme avec
exit(EXIT_SUCCESS);
ou
exit(EXIT_FAILLURE);
?

Merci de votre aide
A voir également:

10 réponses

Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009 46
4 juin 2009 à 01:10
liberer la memoire avant de quitter le programme evite les fuites.
Il n'est mentionné nulle part que le systeme libere la memoire a la fin d'un processus
(il peut eventuellement laisser les valeur et ne plu y toucher ... ce qui engendrerai une faille de sécurité)
certe les OS de maintenant le font (du moins je l'espere Oo) mais n'etant pas sur ...

de plus certaine allocation ne sont pas forcement libérée par le systeme a la fin d'un processus
telle que l'ouverture de socket par exemple ...

EXIT_SUCCESS (0) et EXIT_FAILLURE (1) sont des define,
ils represente la valeur d'une reussite ou d'une erreur.
on peut ecrire 0 ou 1 mais dans un soucis de portabilité, les define sont conseillé
( si l'OS est configuré pour dire 1 = reussi et 0 = erreur )

pour des petits programmes, la valeur de retour n'est pas vraiment importante,
si par contre ton programme est appelé par d'autre,
la valeur de retour sert de test au bon deroulement

la difference entre "return EXIT_SUCCESS" et "exit(EXIT_SUCCESS)"
est que le return quitte la fonction,
tandis qu'exit quitte le programme ...
1
le system d'exploitation ne le fera pas automatiquement?
Si, normalement il le fait, mais disons que c'est une bonne habitude de se préoccuper de libérer la mémoire que l'on a alloué.
Tout programme, lorsqu'il se termine retourne un entier; pourquoi ? Simplement pour informer l'appelant.
Par exemple, sous Unix, lorsque l'on compile le noyau (opération assez longue), on peut lancer la commande suivante:
'make bzImage && make install && make modules_install'
Comme make retourne un code de succès ou d'erreur, le shell saura s'il doit ou non poursuivre l'opération demandée (à quoi bon installer si la commande précédente ne s'est pas bien déroulée?).
Ai-je été assez clair ?
1
Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009 46
4 juin 2009 à 01:43
pour ma part je preconise la suite de return car elle permet une gestion d'erreur ...
et ca ne plait a personne de quitter pour un oui pour un non
(comme dit mon prof .. a la ratp le programme quitte pas quand y a un probleme sur la voie ^^)

en C tu ne peut pas appeller une variable non definie Oo
ou alors je ne connais pas le moyen de faire ca ^^
1
Si je comprends bien, à chaque fois que l'on répond à une de tes questions, tu nous en recolles une demi-douzaine ! On est pas sorti de l'auberge ;-))

je ne sais pas si j'ai bien compris, free() ne sert a rien pour une structure?
J'ai bien peur que tu n'aies pas bien compris, et pourtant c'est très simple et très logique:
- quand tu as appelé 'malloc' pour allouer une zone mémoire, il faut systématiquement appeler 'free' pour libérer cette zone mémoire (enfin quand tu n'en n'as plus besoin!); ensuite il faut considérer cette zone mémoire comme étant inaccessible.

j'ai des tableaux de structure alloué avec malloc() qui sont dans une structure, comment libérer cet espaces mémoire?
Conséquence de la réponse précédente: si tu appelles 'malloc' pour allouer une structure et qu'ensuite tu appelles 'malloc' pour allouer des zones dans cette structure, et bien pour désallouer le tout il faudra faire l'inverse: d'abord désallouer les zones contenues dans la structure et ensuite désallouer la structure elle-même.

aussi je n'ai pas tout compris avec memset() est que ça peut initialiser une structure? et une structure dans la structure?
void* memset (void* bloc, int valeur, size_t longueur)
bloc = adresse du bloc à initialiser,
valeur = valeur de remplissage (convertie en unsigned char),
longueur = nbre d'octets à remplir
retourne un pointeur qui vaut 'bloc'
On peut donc remplir toute zone (allouée dynamiquement ou statiquement) de taille donnée avec une valeur donnée; toute zone, donc pourquoi pas une structure.

et enfin à quoi correspond 0x00?
0x00 signifie 0 en hexa, qui est d'ailleurs la même chose que 0 en décimal, mais pas la même chose que le caractère '0' qui lui vaut 0x30 en hexa et 48 en décimal... ... ;-)

Ouf c'était la dernière question; je sais, je n'ai pas répondu à celle sur SDL, mais je ne sais pas... (en fait, je n'ai pas envie, mais ne le dîtes pas, merci).

Bonne continuation.
1
Atropa Messages postés 1940 Date d'inscription mercredi 25 juin 2008 Statut Membre Dernière intervention 11 mai 2014 274
5 juin 2009 à 04:08
merci loupius pour ta réponse

je pose beaucoup de question c'est vrai mais c'est en posant des questions qu'on apprend !

et personne ne te force à y répondre

merci encore
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Atropa Messages postés 1940 Date d'inscription mercredi 25 juin 2008 Statut Membre Dernière intervention 11 mai 2014 274
4 juin 2009 à 01:37
Merci pour vos réponses,

Elles m'ont pas mal éclaircis il me reste 2 questions :

pour fermer le programme il vaut mieux :
- retourner jusqu'à la fonction main par des return sur toutes les autres fonctions pour qu'elle retourn 1 ou 0
- ou libérer la mémoire et faire exit(); pour finir le programme?

et la seconde question c'était comment savoir si une variable est défini ? en php on peut utiliser isset() par exemple...

Merci encore pour vos réponse, j'ai commencé le C il y a une semaine, c'est aussi très interessant mais pas toujours facile.
0
Atropa Messages postés 1940 Date d'inscription mercredi 25 juin 2008 Statut Membre Dernière intervention 11 mai 2014 274
4 juin 2009 à 02:12
Merci beaucoup,

il ne me reste plus qu'une question du coup: comment kliberer la memoire d'un malloc si on ne sait pas si il a était déclaré?

peut oon faire des free() sur des variables qui n'existe pas?

comment faire?

j'ai envie d'apprendre à faire les choses proprement.
0
Comme l'a dit Brachior, en C des variables qui n'existent pas... ça n'existe pas; le compilateur est là pour l'interdire.
D'autre part, après un 'malloc' on peut toujours faire un free. Si la variable à été soumise à un 'malloc' et que manquent des ressources, le pointeur vaudra NULL, et on peut faire un 'free' sur un pointeur NULL; dans ce cas 'free' ne fait rien.
Si un pointeur est tantôt alloué, tantôt libéré, si bien qu'on ne puisse 'savoir' à un moment donné s'il est alloué ou non, il existe un moyen simple de le savoir: toute libération est suivie d'une affectation de NULL au pointeur, si bien qu'on pourra systématiquement demander un 'free' sans causer de dommage au déroulement du programme.
Toutefois, normalement, on doit suivre l'allocation du pointeur; mais ceci est une autre histoire.
Bonne continuation.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297 > loupius
4 juin 2009 à 08:14
Salut tous.
Il me semble que free(a) ne mets pas a à 0, mais qu'il faut le faire explicitement :
free(a);a=0;
Pour sortir d'un programme, le exit() doit être une exception, et retourner une valeur qui pourra t'aider à localiser l'origine. Un programme bien conçut est un programme qui prévoi tout les cas et fait des traitements en conséquence.
0
loupius > Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023
4 juin 2009 à 13:37
Oui tout à fait, free ne retourne rien et ne met pas le pointeur à NULL.
En disant: toute libération est suivie d'une affectation de NULL au pointeur, je voulais dire qu'après avoir demandé la libération du pointeur, il fallait le mettre à NULL, afin de pouvoir faire ensuite un autre 'free' sans problème.
0
Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009 46
4 juin 2009 à 08:47
"free(a) ne mets pas a à 0"
a NULL tu veux dire ( (void*)0 )

et oui free n'est pas tres bien concu =/
il fonctionne tres bien pour des malloc simple,
mais pour le malloc de structure par exemple,
certain elements sont encore accessible,
c'est pour ca qui est conseillé de faire une "sur couche" de free comme ceci :
void freePlus(void **ptr){
  free(*ptr);
  *ptr = NULL;
}

( le nom de la fct est au choix ^^ )

et si tu fais un free d'une variable qui n'est pas passé par un malloc/calloc, free ne fera rien.
Ces variables sont a la charge du compilateur qui se charge de liberer ces elements.
Sous linux il existe un logiciel du nom de ValGrind qui permet de tracer les fuites memoires ;)

loupius a dit quelque chose qui n'est pas indiqué dans le C,
un malloc ne met pas forcement le pointeur a NULL,
tout depends du syteme en place,
il se peut que ton pointeur est une valeur provenant d'un ancien pointeur.

Par securité, il est conseillé de mettre a NULL apres l'allocation.
(une fonction memset dans la lib string.h est forte utile a ce niveau ...
elle rempli tous les champs d'un pointeur avec un element ...
il s'agit donc de remplir tous les champs pas NULL (0x00))

la fonction calloc fait un malloc et est censée faire le vide apres.
Il reste toujours plus prudent de nettoyer sa place allouée
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
4 juin 2009 à 09:25
Houlà ! attention, tu n'est pas clair, tu mélange valeur de pointeur et valeur pointé.
trouver dans la man page :
"Pour calloc() et malloc(), la valeur renvoyée est un pointeur sur la mémoire allouée, qui est correctement alignée pour n'importe quel type de variable, ou NULL si la demande échoue. "
a+
0
Je dirais même plus c'est pas clair du tout.
malloc, en cas d'erreur, renvoie la valeur NULL; c'est d'ailleurs la seule manière de savoir qu'il y a eu une erreur, il faudrait d'ailleurs systématiquement tester cette valeur.
L'exemple avec 'freePlus' ne change en rien la désallocation d'une structure; elle met simplement la pointeur retourné à NULL, ce qui est une bonne chose. Mais si une structure contient des zones mémoires allouées, elles ne sont pas désallouées car 'free' n'analyse pas la structure; mais il faut noter que le couple 'new'/'delete' ne le fait pas non plus, c'est par le biais des constructeurs/destructeurs qu'on le réalise.
Quant à dire que certain elements sont encore accessible, c'est illusoire et bien souvent temporaire; ils ne sont apparemment accessibles que parce que l'adresse a été conservée, mais on peut aussi mettre n'importe quelle valeur dans le pointeur (dans les limites permises par le système d'exploitation) et lire (voir écrire) des valeurs... mais cela n'a aucun sens ;-)

un malloc ne met pas forcement le pointeur a NULL
Heureusement, sinon il n'y aurait jamais d'allocation.
Le seul point de détail qui différe suivant les systèmes d'exploitation est lorsqu'on demande d'allouer un nombre nul d'octet: GNU répond par un pointeur NULL (c'est-à-dire que rien n'est n'est alloué) alors que d'autre allouent une zone mémoire de 0 octets.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297 > loupius
4 juin 2009 à 15:07
d'autre allouent une zone mémoire de 0 octets
j'ai du mal à voir ce que ça fait. Il te retourne un pointeur mais la mémoire pointé n'est en fait pas alloué, c'est ça ?
En tout cas, c'est original comme comportement. :o)
0
loupius > Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023
5 juin 2009 à 01:11
Original mais réél.
En fait lorsqu'on demande par 'malloc' une zone de x octets, le système en réserve un peu plus car il doit au moins noter la taille demandée qui sera nécessaire pour 'free'; donc allouer une zone de 0 octets, réservera en fait quelques octets et l'adresse retournée par 'malloc' pointera sur une zone dont 0 octets seront disponibles et dans une telle configuration, il faudra malgré tout, faire un appel à 'free' qui libèrera les quelques octets réservés par le système.
0
Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009 46
4 juin 2009 à 09:32
"correctement alignée pour n'importe quel type de variable"
ne veut pas dire que l'espace memoire est propre.
0
Atropa Messages postés 1940 Date d'inscription mercredi 25 juin 2008 Statut Membre Dernière intervention 11 mai 2014 274
4 juin 2009 à 23:39
Merci pour vos réponses,

je voulais utiliser exit() pour quitter le programme par la croix en haut de la fenetre ou alt F4

je ne sais pas si j'ai bien compris, free() ne sert a rien pour une structure?

j'ai des tableaux de structure alloué avec malloc() qui sont dans une structure, comment libérer cet espaces mémoire?

j'ai cherchais la source de SDL_Quit() pour voir comment on peut faire une fonction qui libère la mémoire mais je ne trouve pas dans quel fichier elle est, si quelqu'un sait...

aussi je n'ai pas tout compris avec memset() est que ça peut initialiser une structure? et une structure dans la structure?

et enfin à quoi correspond 0x00?
0
ninouhhichem Messages postés 201 Date d'inscription jeudi 21 mai 2009 Statut Membre Dernière intervention 21 juin 2009 9
5 juin 2009 à 03:16
slt,
return( EXIT_SUCCESS);
c'est fait un kill pour le sous pgr EXIT_SUCCESS
idem pour exit(EXIT_FAILLURE);
0