c - tutorialspoint - strdup library
strcpy vs strdup (5)
Leí que strcpy
es para copiar una cadena, y strdup
devuelve un puntero a una nueva cadena para duplicar la cadena.
¿Podría explicar qué casos prefiere usar strcpy
y qué casos prefiere usar strdup
?
En la respuesta aceptada , la implementación de strdup
se presenta como:
ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);
Sin embargo, eso es algo subóptimo porque tanto strlen
como strcpy
necesitan encontrar la longitud de la cadena comprobando si cada carácter es un /0
.
Usar memcpy
debería ser más eficiente:
char *strdup(const char *src) {
size_t len = strlen(src) + 1;
char *s = malloc(len);
if (s == NULL)
return NULL;
return (char *)memcpy(s, src, len);
}
Las funciones strcpy
y strncpy
son parte de la biblioteca estándar C y operan en la memoria existente. Es decir, debe proporcionar la memoria en la que las funciones copian los datos de cadena, y como corolario, debe tener su propio medio para averiguar cuánta memoria necesita.
Por constrast, strdup
es una función de Posix, y realiza una asignación de memoria dinámica para usted. Devuelve un puntero a la memoria recientemente asignada en la que ha copiado la cadena. Pero ahora eres responsable de este recuerdo y eventualmente debes free
.
Eso hace que strdup
sea una de las funciones de conveniencia de " malloc
oculto", y es de suponer que también por qué no forma parte de la biblioteca estándar. Siempre que use la biblioteca estándar, sabrá que debe llamar a una por cada malloc
/ calloc
. Pero funciones como strdup
introducen un malloc
oculto, y debes tratarlo igual que malloc
con el fin de administrar la memoria. (Otra de esas funciones ocultas de asignación es abi::__cxa_demangle()
. ¡Cuidado!
char *strdup(char *pszSrch)
;
strdup
asignará el almacenamiento del tamaño de la cadena original. Si la asignación de almacenamiento es exitosa, la cadena original se copia a la cadena duplicada.
strdup
d devuelve NULL
en caso de fallo. Si la memoria no está asignada, la copia falla strdup
return NULL
.
strcpy(ptr2, ptr1)
es equivalente a while(*ptr2++ = *ptr1++)
donde como strdup es equivalente a
ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);
(la versión memcpy podría ser más eficiente)
Entonces, si quieres que la cadena que has copiado se use en otra función (como se crea en la sección de montón) puedes usar strdup, sino que strcpy es suficiente.
strdup
asigna memoria para la nueva cadena en el montón, mientras usa strcpy
(o su variante strncpy
más segura) puedo copiar una cadena en una memoria preasignada tanto en el montón como en la pila.