10
votes

Renvoyer une variable allouée

Je sais que nous devrions libérer toute variable allouée avec malloc, mais si je le retourne dans une fonction? Quelque chose comme ceci: xxx

devrais-je libérer str? Comment pourrais-je faire ça?


2 commentaires

L'argument à MALLOC () est presque certainement faux - vous attribuez assez de mémoire pour stocker un char * , mais attribuer à un pointeur qui pointe vers Char < / Code> (et il n'est pas nécessaire de lancer la valeur de retour de MALLOC en C, soit). str = malloc (n * tailleof * str); est un meilleur moyen d'écrire cela.


Comme l'a dit CAF, vous ne devez jamais lancer la valeur de retour de MALLOC (). Voir Stackoverflow.com/Questtions/1565496/... et al


5 Réponses :


13
votes

Vous avez deux options: une, transmettez un char * à une certaine fonction et utilisez-le au lieu d'allouer dans un certain fonctionnement, ou deux, libérez la valeur de retour ultérieurement.

La première option: P>

char *somestr = somefunction(123);
// Do something...
free(somestr);


2 commentaires

Bonne réponse (et question), je suis tombé sur le même problème récemment. Une question: Que se passe-t-il si il est difficile de déterminer à l'avance de la quantité de mémoire dont la valeur de retour de la fonction a besoin? Ensuite, il semblerait plus naturel d'allouer dans la fonction; Sinon, vous auriez besoin d'une manipulation des erreurs dans la fonction pour que l'espace mémoire fourni soit trop petit (par exemple, pour renvoyer une chaîne de longueur variable).


Une chaîne de longueur variable pourrait justifier une mémoire allouée dans la fonction. Je voudrais cependant très hésitant à propos de ce code dans mon propre projet et préférez plutôt spécifier explicitement une longueur maximale choisie sur la base du contexte et des exigences du code. De quelle sorte de chaînes de longueur variable parlez-vous? Ils ne pouvaient pas être plus de plusieurs KB / MB qui pourraient être préalablement alloués?



2
votes

Vous devez libérer tous les espaces alloués, mais si vous le renvoyez, car vous utiliserez ces espaces mémoire dans d'autres parties du programme. Après votre utilisation, vous devez vous libérer. Voir tous les endroits du code qui appelle la fonction et libérez l'espace après avoir utilisé la valeur renvoyée.


0 commentaires

2
votes

Si vous souhaitez renvoyer l'adresse du bloc, vous ne devez pas libérer () le bloc mais comptez plutôt sur le code d'appel pour libérer (). C'est ce qu'on appelle la passation des observations.

Si vous le libérez dans la fonction et renvoyez le pointeur, le code d'appel s'exécutera dans un comportement non défini en essayant d'accéder au bloc déjà libéré. ​​


0 commentaires

4
votes

Vous le libérez lorsque vous avez fini avec elle. Il n'y a aucune règle qui dit que le libre () qui correspond à un Malloc () doit être dans la même fonction.


2 commentaires

Donc, je pourrais faire quelque chose comme Gratuit (STR) de la fonction ou de la liberté (assez)?


Oui en effet. Tout comme vous pouvez faire avec Malloc (), qui est après tout, une autre fonction.



2
votes

Ceci est une pratique pour certaines fonctions existantes ( STRUP () , par exemple) mais est généralement une mauvaise idée. Exiger qu'un utilisateur soit au courant de ce qui se passe à l'intérieur d'un appel de la fonction est une mauvaise exigence - pensez combien de fonctions que vous utilisez qui est internals vous cachée. De manière générale, vous voudrez avoir un utilisateur de passer dans un tampon et une taille au lieu de l'attribuer de mémoire pour eux.


2 commentaires

D'accord, mais si il est difficile de décider à l'avance, combien d'espace sera nécessaire (par exemple créer de manière dynamique une chaîne à remettre). Ensuite, cela semblerait plus naturel (et plus simple) pour la fonction d'allouer autant de mémoire que nécessaire. Qu'est-ce que tu penses?


Un très bon point. Cependant, en réalité, il y aura toujours une longueur supérieure connue à la piqûre, car elle devra s'intégrer dans un champ de base de données ou sur un écran ou une sortie formatée. Bien sûr, il est inutile d'allouer 255 octets lorsque vous n'auriez peut-être pas besoin d'un. Cela dépend donc de ce que vous mettez en œuvre. Je ne m'inquiéterais pas trop dans une application Windows, mais un système intégré sur un micro 8 bits est une bouilloire différente de chevaux colorés.