Le code suivant est utilisé pour trouver le chemin d'un exécutable pour une coque rudimentaire dans C code>. Comme vous pouvez le constater, j'alloque de manière dynamique la variable CODE> PATH CODE>, puis vérifiez si le chemin existe (via
lstat code> dans une fonction d'assistance
cmd_exists code>) . Je retourne ensuite la variable du chemin. Mon problème est que cela provoque une fuite de mémoire, car
chemin code> n'est jamais libéré. Je ne peux pas me libérer de chemin avant de retourner sa valeur et, à ce moment-là, je ne peux penser à aucun moyen de libérer la mémoire qui a été allouée. Si quelqu'un peut m'aider, je l'apprécierais. Merci
3 Réponses :
Vous pouvez demander à l'appelant de libérer la mémoire:
// in caller char * s = find_path("/mypath", "command"); // do something about `s` free(s);
C'est en effet l'un des problèmes de la propriété de la mémoire C. peut être assez difficile, car il n'y a pas de concepts Raii (essentiellement, pas de destructeurs automatiques) en C ++. P>
Je vois 3 solutions comment résoudre ce problème: p>
char * code>, vous ajoutez char * code> et Taille_t code> arguments ( taille_t code> indiquant la taille de la taille de la char * code> tampon en caractères). Ensuite, votre fonction Find_Path peut remplir ce tampon. Voir https://fr.cppreference.com/w/cpp/string/byte / strncpy pour une fonction avec ce comportement. Le problème avec cette approche est que si le tampon n'est pas assez gros, votre fonction doit renvoyer une défaillance et l'appelant doit passer un tampon plus grand. Certaines fonctions de Windows résolvent cela en ayant la fonction renvoyant une taille de tampon "attendue", donc si l'appel échoue (car le tampon n'est pas assez grand), l'appelant peut utiliser la valeur de retour pour voir la taille du tampon et allouer un plus grand tampon. Li>
ul>
Ma solution préférée dépend du cas réel. Je prendrais la troisième alternative s'il existe une taille de tampon maximale significative (comme par exemple un chemin de fichier maximum). Je prendrais la deuxième alternative est une taille tampon maximale est difficile à prédire. En tout cas, je n'utiliserais jamais la première alternative. P>
Pour votre première solution, vous voudrez peut-être utiliser le stockage local du fil pour le faire du thread-Safe.
À mon avis, la deuxième option (c'est la responsabilité de l'appelant à la liberté) est la façon de faire de cela. Il suffit de regarder malloc / calloc: il renvoie un pointeur et c'est votre responsabilité de la libérer. Comme chaque fonction qui renvoie un pointeur vous dit de le libérer (à l'aide d'une fonction spécifique ou de libre), et c'est logique. Pour la dernière partie de votre réponse, s'il y a une taille de tampon maximum significatif, pourquoi la déranger est-elle allouée? Juste donner un tampon statique.
@ Tom's - masloc () code> et
calloc () code> sont des cas spéciaux. Il n'existe aucun moyen de revenir (un pointeur à) la mémoire de taille arbitraire allouée de manière dynamique (dans le sens inconnu de l'appelant jusqu'au temps d'exécution) et être en mesure de s'assurer qu'il est libéré sans rendre l'appelant responsable de la libération . Pratiquement, les deux approches communes que je vois dans le code de production sont les deuxième et troisième. La plupart des temps, je vois le premier est le code écrit par un débutant qui ne comprend pas l'allocation de mémoire dynamique.
Vous devez avoir 2. PRE> gratuit code> dans deux endroits possibles.
cmd_exists code> renvoie false. li>
cmd_existes code> retourne true. li>
ol>
char *temp = find_path(...);
.....//do your stuff
if (temp) free(temp);
Où est cette fonction utilisée?
GRATUIT CODE> Il existe une fois que vous avez terminé. Comment créer un exemple minimal, complet et vérifiable
L'appelant doit libérer la mémoire, car il s'agit maintenant du propriétaire.
Mon problème est que cela provoque une fuite de mémoire, car le chemin n'est jamais libéré? I> Vous pouvez libérer le trajet
code> après la fonction
Find_Path () code> est appelé . Pour E.G
Char * Temp = Find_Path (x, y); code>, puis
gratuit (TEMP) code> Si l'utilisation avec
TEMP code> est terminée.
Demandez à l'appelant fournir le tampon, au lieu de l'attribuer de manière dynamique.
Le retour d'un pointeur sur la mémoire allouée dynamique est pas b> par lui-même une fuite de mémoire. Une fuite de mémoire est quand il n'y a pas de variable de pointeur qui contient l'adresse de la mémoire allouée. Donc, aussi longtemps qu'un appelant sauve la valeur retournée dans une variable de pointeur, c'est bien - pas de fuite de mémoire. Mais votre propre code a des fuites de mémoire. À l'intérieur de votre boucle tandis que vous continuez à allouer la mémoire et à enregistrer l'adresse dans la variable
chemin code>. En d'autres termes - vous continuez à écraser les informations sur la mémoire allouée précédemment et qui est une fuite de mémoire. Si vous avez un
calloc code> dans la boucle, vous avez besoin d'un
gratuit code> aussi.