c - tutorialspoint - strdup library
¿Por qué se considera mal al strdup? (6)
He visto algunos carteles que dicen que strdup
es malo. ¿Hay consenso sobre esto? Lo he usado sin ningún sentimiento de culpabilidad y no veo ninguna razón por la que sea peor que usar malloc
/ memcpy
.
Lo único que puedo pensar que puede ganar una reputación en strdup
es que las personas que llaman pueden hacer un mal uso (por ejemplo, no se dan cuenta de que tienen que liberar la memoria devuelta; intente encontrar hasta el final de una cadena de strdup''ed). Pero entonces, las cuerdas de malloc''ed tampoco están exentas de la posibilidad de un mal uso.
Gracias por las respuestas y disculpas a quienes consideran que la pregunta es inútil (votos para cerrar). En resumen de las respuestas, parece que no existe una sensación general de que el strdup
sea malo per se, sino un consenso general de que, al igual que muchas otras partes de C, se puede usar de manera inadecuada o insegura.
No hay una respuesta ''correcta'' en realidad, pero para aceptarla, acepté la respuesta de @nneoneo; igualmente podría haber sido la respuesta de @R ..
Creo que la mayor parte de la preocupación acerca de strdup proviene de las preocupaciones de seguridad con respecto a las sobrecargas de búfer y las cadenas con formato incorrecto. Si se pasa una cadena terminada que no es nula a strdup, se puede asignar una cadena de longitud no definida. No sé si esto se puede aprovechar específicamente para un ataque, pero en general es una buena práctica de codificación segura usar solo funciones de cadena que tienen una longitud máxima en lugar de confiar solo en el carácter nulo.
Dos razones que se me ocurren:
- No es estrictamente ANSI C, sino POSIX. En consecuencia, algunos compiladores (por ejemplo, MSVC) desalientan el uso (
_strdup
prefiere_strdup
), y técnicamente el estándar C podría definir su propiostrdup
con diferentes semánticas ya questr
es un prefijo reservado. Por lo tanto, hay algunos problemas potenciales de portabilidad con su uso. - Oculta su asignación de memoria. La mayoría de las otras funciones de
str
no asignan memoria, por lo que los usuarios pueden ser engañados (como usted dice) al creer que la cadena devuelta no necesita ser liberada.
Pero, aparte de estos puntos, creo que el uso cuidadoso de strdup
está justificado, ya que puede reducir la duplicación de código y proporciona una buena implementación para expresiones idiomáticas comunes (como strdup("constant string")
para obtener una copia mutable y retornable de un cadena literal).
Mi razón para no gustar a strdup, que no se ha mencionado, es que es una asignación de recursos sin un par natural. Probemos un juego tonto: digo malloc
, tú dices free
. Yo digo que open
ustedes dicen close
. Yo digo create
y decir destroy
. Yo digo strdup
que dices ...?
En realidad, la respuesta a strdup
es free
por supuesto, y la función habría sido mejor llamada malloc_and_strcpy
para dejarlo claro. Pero muchos programadores de C no lo piensan de esa manera y se olvida de que strdup
requiere su opuesto o "finalización" free
para desasignarse.
En mi experiencia, es muy común encontrar fugas de memoria en el código que llama a strdup
. Es una función extraña que combina strlen
, malloc
y strcpy
.
Mi respuesta es más bien compatible con strdup
y no es peor que cualquier otra función en C.
POSIX es un estándar y
strdup
no es demasiado difícil de implementar si la portabilidad se convierte en un problema.Si liberar la memoria asignada por
strdup
no debería ser un problema si alguien se toma un poco de tiempo para leer la página de manual y entender cómo funcionastrdup
. Si uno no entiende cómo funciona una función, es muy probable que la persona vaya a desordenar algo, esto es aplicable a cualquier función, no solo astrdup
.En C, la memoria y la mayoría de las demás cosas son administradas por el programador, por lo que strdup no es peor que olvidarse de liberar la memoria de
malloc
''ed, al no poder terminar con una cadena, usar una cadena de formato incorrecto enscanf
(e invocar un comportamiento indefinido), acceder a la suspensión puntero etc.
(Realmente quería publicar esto como un comentario, pero no pude agregar un solo comentario. Por lo tanto, lo publiqué como una respuesta).
Obviamente, muchas personas no lo hacen, pero personalmente encuentro que strdup
malo por varias razones,
El principal es que oculta la asignación. Las otras funciones de
str*
y la mayoría de las otras funciones estándar no requieren ningún servicio posterior, por lo questrdup
parece lo suficientemente inocuo y puedes olvidarte de limpiar después. dmckee sugirió simplemente agregarlo a su lista mental de funciones que deben limpiarse después, pero ¿por qué? No veo una gran ventaja en reducir dos líneas de longitud media a una corta.Asigna memoria en el montón siempre, y con los VLA de C99 (¿es 99?), Tienes otra razón más para usar
strcpy
(ni siquiera necesitasmalloc
). No siempre puedes hacer esto, pero cuando puedes, debes hacerlo.No es parte del estándar ISO (pero es parte del estándar POSIX, gracias a Wiz), pero ese es realmente un pequeño punto ya que R ... mencionó que se puede agregar fácilmente. Si escribes programas portátiles, no estoy seguro de cómo dirías si ya estaba definido o no ...
Estas son, por supuesto, algunas de mis propias razones, de nadie más. Para responder a su pregunta, no hay consenso que yo sepa.
Si está escribiendo programas solo para usted y no encuentra problema con strdup
, entonces hay muchas menos razones para no usarlo que si está escribiendo un programa para que lo lean muchas personas de muchos niveles de habilidad y edades.
Realmente no he escuchado a strdup
como malvado, pero a algunas personas les puede disgustar:
- No es estándar C (pero está en POSIX). Sin embargo, considero que esta razón es tonta porque es casi una función de una línea para agregar sistemas que no la tienen.
- La duplicación ciega de cadenas en todo el lugar, en lugar de usarlas en el lugar cuando sea posible, desperdicia tiempo y memoria e introduce casos de fallas en el código que, de otro modo, podría estar libre de fallas.
- Cuando necesita una copia de una cadena, es probable que necesite más espacio para modificarla o compilarla, y
strdup
no le ofrece eso.