C: Pourquoi une pile la structure attribuée existent en dehors de la fonction?
-
23-09-2019 - |
Question
ma fonction:
struct hostent * gethost(char * hostname){
if(/*some condition under which I want
to change the mode of my program to not take a host*/){
return null
}
else{
struct hostent * host = gethostbyname(hostname);
return host;
}
}
dans le principal:
struct hostent * host = gethost(argv[2]);
(ignorer toutes les erreurs mineures dans le code, je suis crachant de la mémoire)
cela fonctionne très bien. et Valgrind ne me dit pas que je perds la mémoire, malgré le fait que je ne suis pas libérer.
Pourquoi? Je pensais que des trucs alloué sur la pile disparaît avec l'appel de fonction de retour? ou est-ce parce que je retourne le pointeur? est-ce dangereux de quelque façon?
La solution
host
n'a pas été alloué sur la pile, seulement un pointeur est sur la pile. Le pointeur est copié lorsque la fonction retourne, donc il n'y a rien de mal avec le code.
Notez que gethostbyname
n'alloue pas réellement dynamiquement la mémoire. Il retourne toujours un pointeur sur le même bloc de mémoire alloué statiquement, ce qui explique pourquoi valgrind ne signale pas une fuite. Attention, cependant, parce que cela signifie que vous devez copier le hostent
retourné par votre fonction si vous souhaitez enregistrer la valeur pour plus tard, car d'autres appels à gethost
va le remplacer.
Autres conseils
Il est très bien et ne fuit parce que le pointeur renvoyé ne pointe pas vers les données sur pile ou tas, mais une variable statique.
http://linux.die.net/man/3/gethostbyname :
Les fonctions gethostbyname () et gethostbyaddr () peut retourner pointeurs vers des données statiques, qui peuvent être remplacées par des appels plus tard . Copie du hostent struct ne suffit pas, car il contient des pointeurs; une copie en profondeur est nécessaire.
du manuel:
RETURN VALUE
The gethostbyname() and gethostbyaddr() functions return the hostent
structure or a NULL pointer if an error occurs. On error, the h_errno
variable holds an error number. When non-NULL, the return value may
point at static data, ...
Certaines mémoire est réservée au moment de la compilation (ie. À l'intérieur du code binaire) pour la structure, la fonction renvoie un pointeur vers cette mémoire.
Eh bien la mémoire ne fuit pas jusqu'à ce que toutes les références à elle est perdue, dans votre exemple, le pointeur est retourné donc il y a encore une référence.
Cependant IMHO c'est une mauvaise décision de conception sur la plupart des cas compter sur une autre partie du code pour libérer de la mémoire dynamique. Si la fonction doit retourner un struct par exemple, l'appelant doit le faire et passer un pointeur sur struct.