strdup() - que fait-il en C?
10 réponses
exactement ce que cela ressemble, en supposant que vous êtes habitués à la façon abrégée dans laquelle C et UNIX assigne des mots, il duplique des chaînes :-)
en gardant à l'esprit qu'il ne fait pas partie de la norme ISO C elle-même (a) (c'est une chose POSIX), il fait effectivement la même chose que le code suivant:
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 d'autres termes:
-
Elle tente d'allouer assez de mémoire pour contenir l'ancienne chaîne (plus un '\0' pour marquer la fin de la chaîne).
-
si l'allocation échoue, elle fixe
errno
àENOMEM
et retourneNULL
immédiatement. Le réglage deerrno
àENOMEM
est quelque chose quemalloc
fait en position donc nous n'avons pas besoin de le faire explicitement dans notrestrdup
. Si vous êtes pas POSIX conforme, ISO C ne prescrit pas réellement l'existence deENOMEM
donc je n'ai pas inclus que ici (b) . -
dans les autres cas, l'attribution a fonctionné de sorte que nous copions l'ancienne chaîne à la nouvelle chaîne et que nous retournions la nouvelle adresse (dont l'appelant est responsable de libérer à un moment donné).
Gardez à l'esprit que c'est la définition conceptuelle. Tout rédacteur de bibliothèque valant son salaire peut avoir fourni un code fortement optimisé ciblant le processeur particulier utilisé.
(a) garder à l'esprit, cependant, que les fonctions commençant par str
et une lettre minuscule sont réservées par la norme pour les orientations futures. De C11 7.1.3 Reserved identifiers
:
chaque en-tête déclare ou définit tous les identificateurs énumérés dans sa sous-clause associée, et * déclare optionnellement ou définit les identificateurs énumérés dans la sous-clause connexe sur les orientations futures de la bibliothèque.**
Les orientations futures string.h
peut être trouvée dans C11 7.31.13 String handling <string.h>
:
les noms de fonction commençant par
str
,mem
, ouwcs
et une lettre minuscule peuvent être ajoutés aux déclarations dans l'en-tête<string.h>
.
(b) le changement consisterait essentiellement à remplacer if (d == NULL) return NULL;
par:
if (d == NULL) {
errno = ENOMEM;
return NULL;
}
char * strdup(const char * s)
{
size_t len = 1+strlen(s);
char *p = malloc(len);
return p ? memcpy(p, s, len) : NULL;
}
peut-être que le code est un peu plus rapide qu'avec strcpy()
car le " 151920920 "
char n'a pas besoin d'être recherché à nouveau (il l'était déjà avec strlen()
).
il est inutile de répéter les autres réponses, mais veuillez noter que strdup()
peut faire tout ce qu'il veut du point de vue du C, puisqu'il ne fait partie d'aucune norme du C. Il est cependant défini par POSIX.1-2001.
à Partir de strdup homme :
la fonction strdup()
renvoie un pointeur vers une nouvelle chaîne, qui est une copie de la chaîne pointée par s1
. Le pointeur retourné peut être passé à free()
. Un pointeur null est retourné si la nouvelle chaîne ne peut pas être créée.
Cela fait une copie de la chaîne transmise par l'exécution d'un malloc et strcpy de la chaîne de transmission. Le malloc ed tampon est retourné à l'appelant, d'où la nécessité d'exécuter libre sur la valeur de retour.
strdup() fait l'attribution dynamique de la mémoire pour le tableau de caractères incluant le caractère final '\0' et renvoie l'adresse de la mémoire tas:
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
}
donc, ce qu'il fait c'est nous donner une autre chaîne identique à la chaîne donnée par son argument, sans nous obliger à allouer de la mémoire. Mais nous devons encore la libérer, plus tard.
strdup
et strndup
sont définies dans POSIX systèmes compatibles comme:
char *strdup(const char *str);
char *strndup(const char *str, size_t len);
la fonction strdup () alloue suffisamment de mémoire pour une copie de la
chaîne str
, le copier, et renvoie un pointeur vers elle.
le pointeur peut ensuite être utilisé comme argument pour la fonction free
.
Si la mémoire disponible est insuffisante, NULL
est retourné et errno
est défini à
ENOMEM
.
the strndup () fonction copies at most len
caractères de la chaîne str
always nul terminating the copied string.
la chose la plus précieuse qu'il fait est de vous donner une autre chaîne identique à la première, sans vous obliger à allouer la mémoire (emplacement et taille) vous-même. Mais, comme indiqué, vous avez encore besoin de le libérer (mais qui ne nécessite pas une quantité de calcul, soit.)
la fonction strdup() est un raccourci pour la chaîne duplicate, elle prend un paramètre comme constante de chaîne ou une chaîne littérale et alloue juste assez d'espace pour la chaîne et écrit les caractères correspondants dans l'espace alloué et renvoie finalement l'adresse de l'espace alloué à la routine d'appel.
C'est Simple strcpy(ptr2, ptr1)
c'est équivalent à while(*ptr2++ = *ptr1++)
où strdup est équivalent à
ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);
donc si vous voulez que la chaîne que vous avez copiée soit utilisée dans une autre fonction (comme elle est créée dans la section tas) vous pouvez utiliser strdup, sinon strcpy est suffisant