library - strdup que hace
strdup()-¿Qué hace en C? (10)
De hombre strdup :
La función strdup()
devolverá un puntero a una nueva cadena, que es un duplicado de la cadena apuntada por s1
. El puntero devuelto se puede pasar a free()
. Se devuelve un puntero nulo si no se puede crear la nueva cadena.
¿Cuál es el propósito de la función strdup()
en C?
Exactamente cómo suena, asumiendo que estás acostumbrado a la forma abreviada en que C y UNIX asigna palabras, duplica cadenas :-)
Teniendo en cuenta que en realidad no es parte del estándar ISO C (a) (es una cuestión POSIX), efectivamente hace lo mismo que el siguiente código:
char *strdup (const char *s) {
char *d = malloc (strlen (s) + 1); // Space for length plus nul
if (d == NULL) return NULL; // No memory
strcpy (d,s); // Copy the characters
return d; // Return the new string
}
En otras palabras:
Intenta asignar suficiente memoria para contener la cadena antigua (más un carácter ''/ 0'' para marcar el final de la cadena).
Si la asignación falló, establece
errno
enENOMEM
y devuelveNULL
inmediatamente. La configuración deerrno
enENOMEM
es algo que hacemalloc
en POSIX, por lo que no necesitamos hacerlo explícitamente en nuestrostrdup
. Si no cumple con POSIX, ISO C no exige realmente la existencia deENOMEM
por lo que no lo he incluido aquí (b) .De lo contrario, la asignación funcionó, por lo que copiamos la cadena antigua a la nueva y devolvemos la nueva dirección (que el autor de la llamada es responsable de liberar en algún momento).
Tenga en cuenta que esa es la definición conceptual. Cualquier escritor de la biblioteca que valga su salario puede haber proporcionado un código altamente optimizado dirigido al procesador particular que se está utilizando.
(a) Sin embargo, tenga en cuenta que las funciones que comienzan con str
y una letra minúscula están reservadas por la norma para futuras instrucciones. Desde C11 7.1.3 Reserved identifiers
:
Cada encabezado declara o define todos los identificadores enumerados en su subcláusula asociada, y * opcionalmente declara o define los identificadores enumerados en su subcláusula de direcciones de bibliotecas futuras asociadas. **
Las direcciones futuras para string.h
se pueden encontrar en C11 7.31.13 String handling <string.h>
:
Los nombres de funciones que comienzan con
str
,mem
owcs
y una letra minúscula se pueden agregar a las declaraciones en el encabezado<string.h>
.
(b) El cambio básicamente se reemplazaría if (d == NULL) return NULL;
con:
if (d == NULL) {
errno = ENOMEM;
return NULL;
}
Hace una copia duplicada de la cadena pasada ejecutando un malloc y una cadena de la cadena pasada. El búfer malloc''ed se devuelve a la persona que llama, por lo tanto, la necesidad de correr libremente en el valor de retorno.
It''s Simple strcpy(ptr2, ptr1)
es equivalente a while(*ptr2++ = *ptr1++)
donde como: strdup es equivalente a
ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);
Entonces, si desea que la cadena que ha copiado se use en otra función (como se crea en la sección de almacenamiento dinámico) puede usar strdup, de lo contrario, strcpy es suficiente
La función strdup () es una abreviatura de cadena duplicada, toma un parámetro como una constante de cadena o literal de cadena y asigna el espacio suficiente para la cadena y escribe los caracteres correspondientes en el espacio asignado y finalmente devuelve la dirección de la cadena asignada Espacio a la rutina de llamadas.
Lo más valioso que hace es darte otra cadena idéntica a la primera, sin requerir que asignes memoria (ubicación y tamaño) por ti mismo. Pero, como se indicó, aún necesita liberarlo (pero tampoco requiere un cálculo de cantidad).
No tiene sentido repetir las otras respuestas, pero tenga en cuenta que strdup()
puede hacer lo que quiera desde una perspectiva C, ya que no forma parte de ningún estándar C. Sin embargo, está definido por POSIX.1-2001.
strdup () realiza la asignación de memoria dinámica para la matriz de caracteres, incluido el carácter de final ''/ 0'' y devuelve la dirección de la memoria del montón
char *strdup (const char *s)
{
char *p = malloc (strlen (s) + 1); // allocate memory
if (p != NULL)
strcpy (p,s); // copy string
return p; // return the memory
}
Entonces, lo que hace es darnos otra cadena idéntica a la cadena dada por su argumento, sin requerir que asignemos memoria. Pero todavía tenemos que liberarlo, más tarde.
strdup
y strndup
se definen en los sistemas compatibles con POSIX como:
char *strdup(const char *str);
char *strndup(const char *str, size_t len);
La función strdup () asigna suficiente memoria para una copia de la cadena de caracteres, hace la copia y le devuelve un puntero.
El puntero se puede usar posteriormente como argumento para la función free
.
Si no hay suficiente memoria disponible, se devuelve NULL
y errno
se establece en ENOMEM
.
La función strndup () copia a la mayoría de los caracteres len
de la cadena str
siempre terminando en nulo la cadena copiada.
char * strdup(const char * s)
{
size_t len = 1+strlen(s);
char *p = malloc(len);
return p ? memcpy(p, s, len) : NULL;
}
Tal vez el código sea un poco más rápido que con strcpy()
ya que no es necesario buscar de nuevo el carácter /0
(ya estaba con strlen()
).