strano comportamento di memcpy

Oct 26 2020

Voglio copiare un intero lungo senza segno nel buffer di caratteri byte per byte. Se uso la riga sotto commento, non viene copiata nel buffer.

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

Di seguito è riportato l'output di due analisi con ciascun valore:

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)

Risposte

4 EricPostpischil Oct 26 2020 at 17:42

In esadecimale, 268435456 è 10000000 16 . Il tuo C ++ memorizza i byte di un unsigned longin memoria con il byte di valore basso in precedenza in memoria, quindi questo viene archiviato in memoria come byte con valori 00 16 , 00 16 , 00 16 , 10 16 .

memcpycopia correttamente questi byte in buf.

Quindi, quando strlen(buf)esamina buf, trova prima un byte nullo (00 16 ). Ciò indica che la stringa di caratteri in bufha lunghezza zero, poiché il carattere di terminazione appare immediatamente all'inizio. Quindi strlen(buf)restituisce zero.

Poiché questo valore restituito è assegnato a len, il ciclo for (int i = 0; i < len; i++)esegue zero iterazioni.

Allo stesso modo, in cout << "Value after unsigned long int copy - buf: " << buf << endl;, bufcontiene una stringa di lunghezza zero, quindi nessun carattere viene stampato per essa.

5 eerorika Oct 26 2020 at 17:31

non viene copiato nel buffer.

Sì.

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

Non è chiaro il motivo per cui non ti aspettavi l'output che vedi. 0 è il valore del carattere di terminazione null. Se il byte dell'ordine di memoria più basso dell'intero è 0, il buffer contiene la stringa con terminazione nulla che rappresenta la stringa vuota. In tal caso, l'output visualizzato è prevedibile. Su sistemi little endian (e anche su sistemi big endian dove longè più largo di 4 byte) è il caso di 268435456 che è 0x10'00'00'00 in esadecimale.

Solo perché i byte che hai copiato rappresentano la stringa vuota, non significa che i byte non siano stati copiati.