strcpy frente a memcpy

81

¿Cuál es la diferencia entre memcpy()y strcpy()? Traté de encontrarlo con la ayuda de un programa, pero ambos dan el mismo resultado.

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

Salida

sachin p is [sa], t is [sa]
Sachin Chourasiya
fuente

Respuestas:

127

que se puede hacer para ver este efecto

Compile y ejecute este código:

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

Producirá esta salida:

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

Puede ver que la "ch" fue copiada por memcpy(), pero no strcpy().

egrunin
fuente
1
Hola, sé que la publicación es antigua, pero tengo dos preguntas al respecto. Primero, printf("%2.2x ", *p);¿por qué limitó printf a 2.2? Además, no veo ningún punto ... Segundo: printf("%c", *p ? *p : ' ');¿qué es lo que realmente comprueba esta prueba? Si *p? ¡Gracias de antemano por su respuesta!
Peter Cerba
14
En una declaración printf, "x" significa "base 16". "2.2" significa: dos y solo dos dígitos. La *pprueba significa: "si aciertas un nulo, imprime un espacio".
egrunin
85

strcpyse detiene cuando encuentra un carácter NUL ( '\0'), memcpyno lo hace. No ve el efecto aquí, ya que %sen printf también se detiene en NUL.

Yann Ramin
fuente
2
@Sachin: inicializar py ten algo (todos los espacios en blanco, por ejemplo), luego, después de copiar, comparar p[3]con t[3]. El strcpyno fue más allá p[2], donde encontró el carácter nulo, pero memcpycomo se indicó copió cinco caracteres.
Cascabel
9
Minor pick-pick: strcpy se detiene cuando encuentra el carácter NUL (una "L"). NULL (dos "L") es una constante en tiempo de compilación para un puntero que garantiza que no apunte a ningún objeto válido.
Daniel Stutzbach
Gracias, obtuve la respuesta
Sachin Chourasiya
si dest y src se superponen, strcpy arrojará una falla de seg.
Alcott
12

strcpytermina cuando se encuentra el terminador nulo de la cadena de origen. memcpyrequiere que se pase un parámetro de tamaño. En el caso que presentó, la printfdeclaración se detiene después de que se encuentra el terminador nulo para ambas matrices de caracteres, sin embargo, también encontrará t[3]y t[4]habrá copiado datos en ellas.

fbrereto
fuente
9

strcpy copia el carácter del origen al destino uno por uno hasta que encuentra el carácter NULL o '\ 0' en el origen.

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

donde como memcpycopia datos (no caracteres) desde el origen al destino del tamaño dado n, independientemente de los datos en el origen.

memcpydebe usarse si sabe bien que la fuente contiene otro carácter. para datos encriptados o datos binarios, memcpy es la forma ideal de hacerlo.

strcpyestá en desuso, así que use strncpy.

Viswesn
fuente
3

Debido al carácter nulo en su scadena, printfno mostrará nada más allá de eso. La diferencia entre py testará en los caracteres 4 y 5. pno tendrá ninguno (serán basura) y ttendrá el 'c'y 'h'.

Thomas Jones-Low
fuente
2
  • Diferencia de comportamiento: se strcpydetiene cuando encuentra una NULLo'\0'
  • Diferencia de rendimiento: memcpysuele ser más eficiente que strcpy, que siempre escanea los datos que copia
euccas
fuente
2

La principal diferencia es que memcpy()siempre copia el número exacto de bytes que especifique; strcpy(), por otro lado, copiará hasta que lea un byte NUL (también conocido como 0) y luego se detendrá.

Jeremy Friesner
fuente
1

El problema con su programa de prueba es que printf()deja de insertar el argumento %scuando encuentra una terminación nula \0. Entonces, en su salida probablemente no se haya dado cuenta, que memcpy()copió los caracteres cy htambién.

He visto en GNU glibc-2.24que (para x86) strcpy()solo llama memcpy(dest, src, strlen(src) + 1).

Jaspar L.
fuente
0

printf("%s",...) deja de imprimir los datos cuando se encuentra un valor nulo, por lo que ambas salidas son iguales.

El siguiente código diferencia entre strcpyy memcpy:

#include<stdio.h>
#include<string.h>

int main()
{
    char s[5]={'s','a','\0','c','h'};
    char p[5];
    char t[5];
    int i;
    strcpy(p,s);
    memcpy(t,s,5);
    for(i=0;i<5;i++)
        printf("%c",p[i]);
        printf("\n");
    for(i=0;i<5;i++)
        printf("%c",t[i]);

    return 0;
}
abhijeet keshri
fuente