strdup () - ¿qué hace en C?


¿Cuál es el propósito de la función strdup() en C?

Author: Grijesh Chauhan, 2008-10-31

10 answers

Exactamente cómo suena, asumiendo que estás acostumbrado a la forma abreviada en la que C y UNIX asignan palabras, cadenas duplicadas :-)

Teniendo en cuenta que en realidad no es parte del estándar ISO C en sí (a) (es una cosa POSIX), está haciendo efectivamente 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:

  1. Intenta asignar suficiente memoria para contener la cadena antigua (más un carácter' \0 ' para marcar el final de la cuerda).

  2. Si la asignación falla, establece errno a ENOMEM y devuelve NULL inmediatamente. El ajuste de errno a ENOMEM es algo que malloc hace en POSIX, por lo que no necesitamos hacerlo explícitamente en nuestro strdup. Si no cumple con POSIX, ISO C no exige la existencia de ENOMEM así que no lo he incluido aquí (b).

  3. De lo contrario, la asignación funcionó, por lo que copiamos la cadena antigua a la nueva cadena y devolvemos la nueva dirección (que la persona que llama es responsable de liberar en algún momento).

Tenga en cuenta que esa es la definición conceptual. Cualquier escritor de bibliotecas que valga su salario puede haber proporcionado código altamente optimizado dirigido al procesador en particular que se está utilizando.


(a) Tenga en cuenta, sin embargo, que las funciones que comienzan con str y una letra minúscula están reservadas por el estándar para direcciones futuras. De C11 7.1.3 Reserved identifiers:

Cada cabecera declara o define todos los identificadores listados en su sub-cláusula asociada, y * opcionalmente declara o define identificadores listados en su sub-cláusula de direcciones futuras de biblioteca asociada.**

Las direcciones futuras para string.h se pueden encontrar en C11 7.31.13 String handling <string.h>:

Nombres de funciones que comienzan con str, mem, o wcs y se puede añadir una letra minúscula a las declaraciones en el encabezado <string.h>.


(b) El cambio básicamente sería sustituir if (d == NULL) return NULL; con:

if (d == NULL) {
    errno = ENOMEM;
    return NULL;
}
 326
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-18 09:45:48
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 es un poco más rápido que con strcpy() ya que el carácter \0 no necesita ser buscado de nuevo (ya lo era con strlen()).

 79
Author: Patrick Schlüter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-30 15:38:34

No tiene sentido repetir las otras respuestas, pero tenga en cuenta que strdup() puede hacer lo que quiera desde una perspectiva de C, ya que no es parte de ningún estándar de C. Sin embargo, es definido por POSIX.1-2001.

 50
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-02 14:26:25

De strdup man :

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.

 16
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-02 16:31:28

Hace una copia duplicada de la cadena pasada ejecutando un malloc y strcpy de la cadena pasada. El búfer malloc'ed se devuelve al llamante, de ahí la necesidad de ejecutar free en el valor devuelto.

 3
Author: jussij,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-31 07:22:27

Strdup() hace la asignación dinámica de memoria para la matriz de caracteres incluyendo el carácter 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.

 3
Author: Karshit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-04 14:27:41

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 string str, hace la copia, y devuelve un puntero a ella.

El puntero puede utilizarse 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 como máximo los caracteres len de la string str siempre null termina la cadena copiada.

 2
Author: Sujay Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-18 11:00:47

Lo más valioso que hace es darle otra cadena idéntica a la primera, sin requerir que usted mismo asigne memoria (ubicación y tamaño). Pero, como se señaló, todavía necesita liberarlo (pero que no requiere un cálculo de cantidad, tampoco.)

 1
Author: dkretz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-31 07:27:02

La función strdup() es una abreviatura de string duplicate, toma un parámetro como una constante de cadena o un 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 del espacio asignado a la rutina de llamada.

 1
Author: AnkitSablok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-13 05:49:36

Es Simple strcpy(ptr2, ptr1) es equivalente a while(*ptr2++ = *ptr1++)

Donde as: strdup es equivalente a

ptr2 = malloc(strlen(ptr1)+1);

strcpy(ptr2,ptr1);

Así que si quieres que la cadena que has copiado se use en otra función (como se crea en la sección heap) puedes usar strdup, de lo contrario strcpy es suficiente

 0
Author: Md. Al Amin Bhuiyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-03 09:04:04