strcpy vs strdup

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 ?

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.

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 sus propios medios 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!

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 en el montón o en la stack.

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); } 

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 .