memcpy'nin tuhaf davranışı
İşaretsiz uzun bir tamsayıyı bayt bayt karakter tamponuna kopyalamak istiyorum. Yorumun altındaki satırı kullanırsam, arabelleğe kopyalanmaz.
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şağıda, her bir değerle iki çalışmanın çıktısı verilmiştir:
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)
Yanıtlar
Onaltılık olarak 268435456, 10000000 16'dır . C ++ 'nız, unsigned longbellekte daha önce düşük değerli bayta sahip bir bellekteki baytları depolar , bu nedenle bu, 00 16 , 00 16 , 00 16 , 10 16 değerlerine sahip baytlar olarak bellekte depolanır .
memcpybu baytları doğru şekilde buf.
Daha sonra strlen(buf)incelediğinde bufönce boş bayt (00 16 ) bulur . Bu, karakter dizisinin bufsıfır uzunluğa sahip olduğunu gösterir , çünkü sonlandırma karakteri hemen başında görünür. Yani strlen(buf)sıfır döndürür.
Bu dönüş değeri atandığından lendöngü for (int i = 0; i < len; i++)sıfır yineleme gerçekleştirir.
Benzer şekilde, içinde cout << "Value after unsigned long int copy - buf: " << buf << endl;, bufhiçbir karakter bunun için basılır, böylece sıfır uzunlukta bir dize içerir.
arabelleğe kopyalanmaz.
Evet öyle.
cout << ... << buf << endl; const int len = strlen(buf);
Gördüğünüz çıktıyı neden beklemediğiniz açık değil. 0, boş sonlandırıcı karakterin değeridir. Tamsayının en düşük bellek sırası baytı 0 ise, arabellek, boş dizgeyi temsil eden null ile sonlandırılmış dizeyi içerir. Böyle bir durumda, gördüğünüz çıktı beklenebilir. Küçük endian sistemlerde (ve ayrıca long4 bayttan daha geniş olan büyük endian sistemlerinde ) bu, 268435456 için geçerli olan, onaltılık olarak 0x10'00'00'00'dür.
Kopyaladığınız baytların boş dizeyi temsil etmesi, baytların kopyalanmadığı anlamına gelmez.