dziwne zachowanie memcpy
Chcę skopiować nieoznaczoną długą liczbę całkowitą do bufora char bajt po bajcie. Jeśli używam linii pod komentarzem, nie jest ona kopiowana do bufora.
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]);
}
Poniżej przedstawiono wyniki dwóch przebiegów z każdą wartością:
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)
Odpowiedzi
Szesnastkowo 268435456 to 10000000 16 . Twój C ++ przechowuje bajty unsigned longw pamięci z bajtem o niskiej wartości wcześniej w pamięci, więc jest on przechowywany w pamięci jako bajty o wartościach 00 16 , 00 16 , 00 16 , 10 16 .
memcpypoprawnie kopiuje te bajty do buf.
Następnie podczas strlen(buf)badania najpierw bufznajduje bajt zerowy (00 16 ). Oznacza to, że ciąg znaków w bufma zerową długość, ponieważ znak kończący pojawia się natychmiast na początku. Więc strlen(buf)zwraca zero.
Ponieważ ta wartość zwracana jest przypisana do len, pętla for (int i = 0; i < len; i++)wykonuje zerowe iteracje.
Podobnie, w cout << "Value after unsigned long int copy - buf: " << buf << endl;, bufzawiera ciąg zerowej długości, więc żadne znaki są drukowane na nim.
nie jest kopiowany do bufora.
Tak to jest.
cout << ... << buf << endl; const int len = strlen(buf);
Nie jest jasne, dlaczego nie spodziewałeś się rezultatu, który widzisz. 0 jest wartością znaku kończącego wartość null. Jeśli najniższy bajt kolejności pamięci liczby całkowitej wynosi 0, wówczas bufor zawiera ciąg zakończony znakiem null, który reprezentuje pusty ciąg. W takim przypadku oczekiwany jest wynik, który widzisz. W systemach typu little endian (a także w systemach big endian, w których longjest szersza niż 4 bajty), tak się dzieje w przypadku 268435456, czyli 0x10'00'00'00 szesnastkowo.
Tylko dlatego, że skopiowane bajty reprezentują pusty ciąg, nie oznacza, że bajty nie zostały skopiowane.