J'ai vu des affiches indiquant que strdup
est diabolique. Y a-t-il un consensus à ce sujet? Je l'ai utilisé sans aucun sentiment de culpabilité et je ne vois aucune raison pour laquelle c'est pire que d'utiliser malloc
/memcpy
.
La seule chose que je peux penser pourrait gagner une réputation strdup
, c’est que les appelants pourraient en faire un mauvais usage (par exemple, ne pas se rendre compte qu’ils doivent libérer la mémoire retournée; essayer de strcat jusqu’à la fin d’une chaîne de caractères). Mais alors les cordes mallocées ne sont pas exemptes de la possibilité d’abus.
Merci pour les réponses et excuses à ceux qui considèrent que la question est inutile (vote à venir). En résumé, il semble qu'il n'y ait pas de sentiment général que strdup
soit un mal en soi, mais un consensus général selon lequel il peut, comme beaucoup d'autres parties de C, être utilisé de manière incorrecte ou non sécurisée.
Il n’existe pas vraiment de réponse «correcte», mais pour en accepter une, j’ai accepté la réponse de @nneoneo - elle aurait également pu être celle de @R ...
Je peux penser à deux raisons:
_strdup
) et techniquement le standard C pourrait définir sa propre strdup
avec une sémantique différente puisque str
est un préfixe réservé. Son utilisation pose donc certains problèmes de portabilité.str
n'allouent pas de mémoire. Par conséquent, les utilisateurs peuvent être induits en erreur (comme vous le dites) en leur faisant croire que la chaîne renvoyée n'a pas besoin d'être libérée.Mais, mis à part ces points, je pense qu’une utilisation prudente de strdup
est justifiée, car elle peut réduire la duplication de code et fournit une implémentation de Nice pour les idiomes courants (telle que strdup("constant string")
pour obtenir une copie modifiable et renvoyable d’une chaîne littérale).
Ma réponse est plutôt en faveur de strdup
et ce n’est pas pire que toute autre fonction en C.
POSIX est un standard et strdup
n'est pas trop difficile à mettre en œuvre si la portabilité devient un problème.
La possibilité de libérer la mémoire allouée par strdup
ne devrait pas être un problème si quelqu'un prenait un peu de temps pour lire la page de manuel et comprendre comment fonctionne strdup
. Si on ne comprend pas le fonctionnement d'une fonction, il est très probable que la personne va gâcher quelque chose, cela s'applique à la fonction toute, pas seulement à strdup
.
En C, la mémoire et la plupart des choses sont gérées par le programmeur, donc strdup n'est pas pire que d'oublier la mémoire libremalloc
'ed, échouant à fin nulle une chaîne utilisant un format incorrect chaîne dans scanf
(et invoquant un comportement indéfini), accédant à suspendu pointeur, etc.
(Je voulais vraiment poster ceci en tant que commentaire, mais je ne pouvais pas ajouter un seul commentaire. Par conséquent, posté en réponse).
Je n'ai pas vraiment entendu strdup
décrit comme étant diabolique, mais il y a des raisons pour lesquelles certaines personnes ne l'aiment pas:
strdup
ne vous en donne pas la possibilité.Je pense que la majorité des préoccupations concernant strdup provient de préoccupations de sécurité concernant les dépassements de mémoire tampon et les chaînes mal formatées. Si une chaîne terminée non nulle est transmise à strdup, une chaîne de longueur non définie peut être allouée. Je ne sais pas si cela peut être spécifiquement utilisé dans une attaque, mais en général, il est recommandé de n'utiliser que des fonctions de chaîne qui prennent une longueur maximale au lieu de s'appuyer uniquement sur le caractère nul.
Évidemment, beaucoup de gens ne le font pas, mais personnellement, je trouve strdup
mal pour plusieurs raisons,
le principal étant cela cache l'allocation. Les autres fonctions str*
et la plupart des fonctions standard ne nécessitent pas free
par la suite. strdup
a donc l’air assez inoffensif et vous pouvez oublier de nettoyer après. dmckee a suggéré de simplement l'ajouter à votre liste mentale de fonctions qui doivent être nettoyées après, mais pourquoi? Je ne vois pas un grand avantage à réduire deux lignes de longueur moyenne à une seule.
Il alloue toujours de la mémoire sur le tas, et avec les VLA de C99 (est-ce 99?), Vous avez encore une autre raison d'utiliser simplement strcpy
(vous n'avez même pas besoin de malloc
). Vous ne pouvez pas toujours faire cela, mais quand vous le pouvez, vous devriez le faire.
Cela ne fait pas partie de la norme ISO (mais ça fait partie de la norme POSIX, merci Wiz), mais c'est vraiment un petit point, car R .. a mentionné que cela peut être ajouté facilement. Si vous écrivez des programmes portables, je ne sais pas comment vous diriez s'il est déjà défini ou non ...
Ce sont bien sûr quelques-unes de mes propres raisons, personne d'autre. Pour répondre à votre question, il n'y a pas de consensus à ma connaissance.
Si vous écrivez des programmes uniquement pour vous-même et que strdup
ne pose aucun problème, il y a donc beaucoup moins de raisons de ne pas l'utiliser que si vous écrivez un programme destiné à être lu par de nombreuses personnes de différents niveaux et techniques.
La raison pour laquelle je n'aime pas strdup, ce qui n'a pas été mentionné, est qu'il s'agit d'une allocation de ressources sans paire naturelle. Essayons un jeu idiot: je dis malloc
, vous dites free
. Je dis open
vous dites close
. Je dis create
vous dites destroy
. Je dis strdup
vous dites ....?
En fait, la réponse à strdup
est free
bien sûr, et la fonction aurait été mieux nommée malloc_and_strcpy
pour que cela soit clair. Mais beaucoup de programmeurs C ne le voient pas de cette façon et oublient que strdup
nécessite son opposé ou "fin" free
pour désallouer.
D'après mon expérience, il est très courant de trouver des fuites de mémoire dans le code appelé strdup
. C'est une fonction étrange qui combine strlen
, malloc
et strcpy
.