J'essaie actuellement de déterminer le meilleur moyen de programmer fonctionnellement en C, mais j'ai un problème pour libérer la mémoire après avoir été allouée.
Considérez l'exemple suivant: (J'ai supprimé les parties sans importance parce que Je pensais que ce serait trop long) p> ici, étant donné que la convientation est appelée à l'intérieur de printf, et il semble y avoir aucun moyen de libérer la mémoire qui a été allouée à la chaîne. Notez que ce code compile avec GCC, mais je recherche un moyen de réduire l'ensemble de la charge de la mémoire. P> Je pourrais définir une variable temporaire et libérer plus tard dans la fonction principale, mais le code serait Soyez plus difficile à lire car les fonctions sont plus imbriquées. P> P>
3 Réponses :
Vous devez utiliser une variable temporaire afin que vous puissiez libérer plus tard. Sinon, vous aurez une fuite de mémoire chaque fois que vous appelez la fonction comme celle-ci. P>
C n'a aucune forme de gestion automatique de la mémoire, sauf que la plupart des systèmes d'exploitation récupéreront toute la mémoire privée du processus lorsqu'elle se termine. Malheureusement, cela signifie que votre programme devra être un peu plus verbeux. P>
Je pense que le système d'exploitation est celui qui est responsable de la libération de la mémoire lors de la résiliation, mais cela est probablement très pédant. +1
@Neil Droite. J'ai supposé que libérer toute la mémoire était l'un des nettoyages que quitter () code> fait, mais j'avais tort.
Tout simplement allouer le tampon en principal et transmettez-le sous forme de paramètre à la fonction afin qu'elle puisse la peupler. De cette façon, vous n'avez pas besoin d'avoir des variables globales.
//... some code ...
int someFunction(int someParam, char *output, int somesize)
{
//... some code ...
// update a maximum of 'somesize' of output
snprintf(output, somesize, "some special string");
//... some code ...
return strlen("some special string");
}
int main()
{
char buffer[somesize]; // or use malloc and free at the end
//... some code ...
if (someFunction(someParam, buffer, somesize) > 0) {
printf("%s\n", buffer);
}
return 0;
}
C'est pourquoi je ne les ai pas ajoutées :)
Statut CODE> n'est pas utilisé, ce qui pourrait provoquer .Problèmes qu'elle décrivent la validité de la mémoire tampon code>.
Cela a-t-il vraiment besoin d'être un exemple complet? :)
Je reçois le point, mais malheureusement, la taille de la chaîne est inconnue à l'avance. Donc, je voudrais probablement rester à Malloc () à l'intérieur de la même manière et libérant la valeur retournée dans Main ()
Cela dépend clairement de ce que vous faites, mais vous pouvez renvoyer une erreur si le tampon n'est pas assez grand ou un type personnalisé qui est transmis comme paramètre. C'est à dire. Au lieu de "Char * Sortie, int Somésize" ont "mytype * var;" où mytype pourrait être "Typeft struct {int si grande taille; char * tampon;};" de sorte que vous l'allouez dans le principal et que vous l'appelez comme suit: "mytype var; quelque fonctionnement (quelqueparame, et var);" Et en quelque sorte, vous allouez le tampon. puis créez un assistant pour libérer (mytype);
Si vous voulez vraiment avoir ce style fonctionnel, vous pouvez transmettre un argument supplémentaire (pointeur) où vous enregistrez tout ce qui doit être nettoyé:
char* someFunction(int someParam, void **cleanup)
{
//... some code ...
char* str = malloc((strlen)*sizeof(char));
//... some code ...
*cleanup = str;
return(str);
}
int main()
{
void *cleanup = 0;
//... some code ...
printf("%s\n", someFunction(someParam, &cleanup));
free(cleanup);
return 0;
}
C'est une fuite de mémoire; Attribuez-la une variable dans
principale code>, puislibres code> serait un moyen de le réparer."Mais le code serait plus difficile à lire". Rendre le code plus facile à lire est définitivement important mais est secondaire pour rendre le code fonctionnellement correct. Donc, votre idée d'une variable TEMP est la bonne façon de le faire.
J'espérais faire des fonctions fortement imbriquées dans le style ou le style LISP, mais je suppose que ce serait difficile.
Un autre style est destiné à l'appelant de fournir la mémoire et de transmettre cela comme un pointeur dans la fonction. Dans ce cas, l'appelant peut utiliser une variable automatique qui n'a pas besoin d'être libérée ou dans le cas de
principal code>, il peut même utiliser une mémoire dynamique qui sera libérée automatiquement lorsque le processus se déroule. Bien sûr, il existe des compromis avec cette approche également, ce qui évite d'éviter de grandes variables automatiques sur la pile.