me he vuelto su código en un ejemplo compilables completa. También agregué una tercera matriz de un "normal" char
que en mi entorno está firmado.
#include <cstring>
#include <cstdio>
using std::memcpy;
using std::printf;
int main()
{
unsigned char array[] = {'\xc0', '\x3f', '\x0e', '\x54', '\xe5', '\x20'};
unsigned char array2[6];
char array3[6];
memcpy(array2, array, 6);
memcpy(array3, array, 6);
printf("%x %x %x %x %x %x\n", array[0], array[1], array[2], array[3], array[4], array[5]);
printf("%x %x %x %x %x %x\n", array2[0], array2[1], array2[2], array2[3], array2[4], array2[5]);
printf("%x %x %x %x %x %x\n", array3[0], array3[1], array3[2], array3[3], array3[4], array3[5]);
return 0;
}
Mis resultados fueron los que esperaba.
c0 3f e 54 e5 20
c0 3f e 54 e5 20
ffffffc0 3f e 54 ffffffe5 20
Como se puede ver, sólo cuando la matriz es de un tipo char firmado hacer el 'extra' ff
conseguir adjuntas. El motivo es que cuando memcpy
rellena la matriz del char
con signo, los valores con un alto bit establecido ahora corresponden a los valores negativos char
. Cuando se pasa al printf
, el char
se promociona a los tipos int
, lo que significa una extensión de signo.
%x
los imprime en hexadecimal como si fueran unsigned int
, pero a medida que el argumento se pasa como int
el comportamiento es técnicamente definido. Por lo general, en una máquina complementaria de dos, el comportamiento es el mismo que el estándar firmado para conversión sin signo que usa la aritmética mod 2^N (donde N es el número de bits de valor en unsigned int
). Como el valor fue solo "ligeramente" negativo (procedente de un tipo firmado estrecho), la conversión posterior está cerca del valor unsigned int
máximo posible, es decir, tiene muchos 1
(en binario) o f
en hexadecimal.
¿Puedes verificar la definición de 'array2'? –
Parece tratar array2 como ints con signo en lugar de caracteres sin signo. –
array2 es un char sin signo [] – Hock