77 votes

strcpy vs strdup

J'ai lu que strcpy sert à copier une chaîne de caractères, et strdup renvoie un pointeur vers une nouvelle chaîne de caractères pour dupliquer la chaîne.

Pourriez-vous expliquer dans quels cas vous préférez utiliser strcpy et dans quels cas préférez-vous utiliser strdup ?

109voto

Abdul Muheedh Points 471

strcpy(ptr2, ptr1) est équivalent à while(*ptr2++ = *ptr1++)

alors que strdup est équivalent à

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

( version memcpy pourrait être plus efficace)

Ainsi, si vous voulez que la chaîne que vous avez copiée soit utilisée dans une autre fonction (car elle est créée dans la section heap), vous pouvez utiliser strdup, sinon strcpy est suffisant.

6 votes

Bonne réponse, à l'exception de la dernière phrase, qui prête à confusion. Je suppose que vous voulez dire la durée de vie de la strdup() peut s'étendre au-delà de la fin de la fonction actuelle, mais cela pourrait être le cas de toute façon (si la cible de la fonction strcpy() est un tampon fourni par l'appelant, une variable globale, ou elle-même allouée manuellement en utilisant la fonction malloc() o new ).

1 votes

Oui, il est vrai que si le tampon fourni par l'appelant est une variable globale ou un pointeur dynamique, il n'est pas nécessaire d'utiliser strdup. J'ai juste indiqué un des scénarios d'utilisation et merci de l'avoir complété.

9 votes

J'aime beaucoup le while(*ptr2++ = *ptr1++) ! :)

58voto

Kerrek SB Points 194696

Les fonctions strcpy y strncpy font partie de la bibliothèque standard du langage C et opèrent sur la mémoire existante. C'est-à-dire, vous doit fournir la mémoire dans laquelle les fonctions copient les données de la chaîne, et comme corollaire, vous Vous devez avoir votre propre moyen de déterminer la quantité de mémoire dont vous avez besoin.

Par contraste, strdup est une fonction Posix, et elle effectue l'allocation dynamique de la mémoire pour vous. Elle renvoie un pointeur vers la mémoire nouvellement allouée dans laquelle elle a copié la chaîne. Mais vous sont maintenant responsables de cette mémoire et doivent éventuellement free il.

Cela fait strdup l'un des "cachés malloc "C'est sans doute aussi pour cette raison qu'elle ne fait pas partie de la bibliothèque standard. Tant que vous utilisez la bibliothèque standard, vous savez que vous devez appeler une fonction free pour chaque malloc / calloc . Mais des fonctions telles que strdup introduire une malloc et vous devez le traiter de la même manière qu'une malloc pour des raisons de gestion de la mémoire. (Une autre fonction d'allocation cachée de ce type est la fonction d'allocation de GCC abi::__cxa_demangle() .) Attention !

1 votes

Ahh, je me suis toujours demandé pourquoi ce n'était pas dans stdlib, et maintenant je sais.

14voto

Oren Points 1210

strdup alloue de la mémoire pour la nouvelle chaîne de caractères sur le tas, tandis que l'utilisation de l'option strcpy (ou sa version plus sûre strncpy varient), je peux copier une chaîne de caractères dans une mémoire pré-allouée sur soit le tas ou la pile.

1 votes

Pourquoi ce "soit" emphatique ? N'est-il pas possible d'utiliser strcpy à copier dans un tampon statique ?

0 votes

J'ai essayé de souligner la différence d'utilisation entre les deux fonctions sans encombrer la réponse avec trop de problèmes de gestion de la mémoire. Mais oui, vous avez raison au sujet des tampons statiques.

0 votes

Si vous ne voulez pas être encombré, vous pouvez simplement terminer la réponse après "mémoire pré-allouée" :-)

12voto

Heikki Salokanto Points 211

Dans le réponse acceptée la mise en œuvre de strdup est présenté comme :

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

Cependant, c'est un peu sous-optimal car à la fois strlen y strcpy il faut trouver la longueur de la chaîne en vérifiant si chaque caractère est un \0 .

Utilisation de memcpy devrait être plus efficace :

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

0voto

char *strdup(char *pszSrch) ;

strdup allouera un espace de stockage de la taille de la chaîne originale. Si l'allocation de mémoire est réussie, la chaîne originale est copiée dans la chaîne dupliquée.

strdup d retour NULL en cas d'échec. Si la mémoire n'est pas allouée, la copie échoue strdup retourner NULL .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X