comportamiento extraño de memcpy

Oct 26 2020

Quiero copiar un entero largo sin firmar en el búfer de caracteres byte por byte. Si utilizo la línea debajo del comentario, no se copia al búfer.

    char buf[128];
    //unsigned long int_val = 268435456;
    unsigned long int_val = 293456376;

    cout << "Value of int_val: " << int_val << endl;

    memset(buf, 0, sizeof(buf));

    memcpy(buf, &int_val, sizeof(long));
    cout << "Value after unsigned long int copy - buf: " << buf << endl;

    const int len = strlen(buf);
    cout << "buf" << endl << "====" << endl;
    for (int i = 0; i < len; i++)
    {
        printf("%3d (0x%02X)\n", buf[i], buf[i]);
    }

A continuación se muestra la salida de dos ejecuciones con cada valor:

Value of int_val: 268435456
Value after unsigned long int copy - buf:
buf
===

Value of int_val: 293456376
Value after unsigned long int copy - buf: ��}
buf
===
 -8 (0xFFFFFFF8)
-55 (0xFFFFFFC9)
125 (0x7D)
 17 (0x11)

Respuestas

4 EricPostpischil Oct 26 2020 at 17:42

En hexadecimal, 268435456 es 10000000 16 . Su C ++ almacena los bytes de an unsigned longen la memoria con el byte de valor bajo anteriormente en la memoria, por lo que esto se almacena en la memoria como bytes con los valores 00 16 , 00 16 , 00 16 , 10 16 .

memcpycopia correctamente estos bytes en buf.

Luego, cuando strlen(buf)examina buf, encuentra primero un byte nulo (00 16 ). Esto indica que la cadena de caracteres en buftiene una longitud cero, ya que el carácter final aparece inmediatamente al principio. Entonces strlen(buf)devuelve cero.

Dado que se asigna este valor de retorno len, el bucle for (int i = 0; i < len; i++)realiza cero iteraciones.

De manera similar, in cout << "Value after unsigned long int copy - buf: " << buf << endl;, bufcontiene una cadena de longitud cero, por lo que no se imprimen caracteres para ella.

5 eerorika Oct 26 2020 at 17:31

no se copia al búfer.

Sí lo es.

cout << ... << buf << endl;
const int len = strlen(buf);

No está claro por qué no esperaba el resultado que ve. 0 es el valor del carácter terminador nulo. Si el byte de orden de memoria más bajo del entero es 0, entonces el búfer contiene la cadena terminada en nulo que representa la cadena vacía. En tal caso, es de esperar la salida que ve. En los sistemas little endian (y también en los sistemas big endian donde longes más ancho que 4 bytes) ese es el caso de 268435456 que es 0x10'00'00'00 en hexadecimal.

El hecho de que los bytes que copió representan la cadena vacía no significa que los bytes no se copiaron.