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]

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().


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.


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.


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.


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'.


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

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á.


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).


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;
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.