странное поведение memcpy

Oct 26 2020

Я хочу скопировать длинное целое число без знака в буфер char побайтно. Если я использую строку под комментарием, она не копируется в буфер.

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

Ниже приведены результаты двух прогонов с каждым значением:

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)

Ответы

4 EricPostpischil Oct 26 2020 at 17:42

В шестнадцатеричном формате 268435456 равно 10000000 16 . Ваш C ++ хранит байты unsigned longв памяти с младшим байтом ранее в памяти, поэтому он сохраняется в памяти в виде байтов со значениями 00 16 , 00 16 , 00 16 , 10 16 .

memcpyправильно копирует эти байты в buf.

Затем при strlen(buf)проверке bufсначала находит нулевой байт (00 16 ). Это указывает на то, что строка символов bufимеет нулевую длину, так как завершающий символ появляется сразу в начале. Так что strlen(buf)возвращает ноль.

Поскольку это возвращаемое значение присвоено len, цикл не for (int i = 0; i < len; i++)выполняет итераций.

Точно так же, в cout << "Value after unsigned long int copy - buf: " << buf << endl;, bufсодержит строку нулевой длины, поэтому никаких символов не печатается для него.

5 eerorika Oct 26 2020 at 17:31

он не копируется в буфер.

Да, именно так.

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

Непонятно, почему вы не ожидали того результата, который видите. 0 - это значение нулевого символа конца. Если младший байт порядка памяти целого числа равен 0, то буфер содержит строку с завершающим нулем, которая представляет собой пустую строку. В таком случае результат, который вы видите, является ожидаемым. В системах с longпрямым порядком байтов (а также в системах с прямым порядком байтов, длина которых превышает 4 байта), это имеет место для 268435456, что составляет 0x10'00'00'00 в шестнадцатеричном формате.

То, что скопированные вами байты представляют собой пустую строку, не означает, что байты не были скопированы.