web-dev-qa-db-fra.com

strcpy vs memcpy

Quelle est la différence entre memcpy () et strcpy ()? J'ai essayé de le trouver à l'aide d'un programme, mais les deux donnent le même résultat.

int main()
{
    char s[5]={'s','a','\0','c','h'};
    char p[5];
    char t[5];
    strcpy(p,s);
    memcpy(t,s,5);
    printf("sachin p is [%s], t is [%s]",p,t);
    return 0;
}

Sortie 

sachin p is [sa], t is [sa]
64

ce qui pourrait être fait pour voir cet effet

Compilez et exécutez ce code:

void dump5(char *str);

int main()
{
    char s[5]={'s','a','\0','c','h'};

    char membuff[5]; 
    char strbuff[5];
    memset(membuff, 0, 5); // init both buffers to nulls
    memset(strbuff, 0, 5);

    strcpy(strbuff,s);
    memcpy(membuff,s,5);

    dump5(membuff); // show what happened
    dump5(strbuff);

    return 0;
}

void dump5(char *str)
{
    char *p = str;
    for (int n = 0; n < 5; ++n)
    {
        printf("%2.2x ", *p);
        ++p;
    }

    printf("\t");

    p = str;
    for (int n = 0; n < 5; ++n)
    {
        printf("%c", *p ? *p : ' ');
        ++p;
    }

    printf("\n", str);
}

Il produira cette sortie:

73 61 00 63 68  sa ch
73 61 00 00 00  sa

Vous pouvez voir que le "ch" a été copié par memcpy(), mais pas strcpy().

104
egrunin

strcpy s'arrête lorsqu'il rencontre une valeur NULL, memcpy ne le fait pas. Vous ne voyez pas l'effet ici, car %s dans printf s'arrête également à NULL.

64
Yann Ramin

strcpy se termine lorsque le terminateur null de la chaîne source est trouvé. memcpy nécessite qu'un paramètre de taille soit passé. Dans le cas où vous avez présenté, l'instruction printf est interrompue une fois que le terminateur null a été trouvé pour les deux tableaux de caractères, mais t[3] et t[4] y ont également copié des données.

12
fbrereto

strcpy copie le caractère de la source à la destination un par un jusqu'à ce qu'il trouve le caractère NULL ou '\ 0' dans la source.

while((*dst++) = (*src++));

où as memcpy copie les données (et non les caractères) de la source à la destination d'une taille donnée n, quelles que soient les données de la source.

memcpy devrait être utilisé si vous savez bien que la source contient autre chose que du caractère. memcpy est le moyen idéal pour les données cryptées ou binaires.

strcpy est obsolète, utilisez donc strncpy.

9
Viswesn

En raison du caractère nul dans votre chaîne, le printf ne montrera rien au-delà de cela. La différence entre p et t sera dans les caractères 4 et 5. p n'aura pas (ils seront des ordures) et t aura les «c» et «h». 

3
Thomas Jones-Low

La principale différence est que memcpy () copie toujours le nombre exact d'octets que vous spécifiez. strcpy (), par contre, copiera jusqu'à lire un octet NUL (aka 0), puis s'arrêtera après cela.

2
Jeremy Friesner
  • Différence de comportement: strcpy s'arrête lorsqu'il rencontre une NULL ou '\0'
  • Différence de performances: memcpy est généralement plus efficace que strcpy, qui analyse toujours les données copiées.
1
euccas

Le problème avec votre programme de test est que la printf() cesse d'insérer l'argument dans %s, quand il rencontre un \0-terminaison nul __ Donc, vous n'avez probablement pas remarqué dans votre sortie que memcpy() a copié les caractères c et h bien.

J'ai vu dans GNU glibc-2.24, que (pour x86) strcpy() appelle simplement memcpy(dest, src, strlen(src) + 1).

0
Jaspar L.