Преобразовать символ memcpy [] в строку

#c

#c

Вопрос:

Мне нужно:

  1. преобразуйте символ uint64 memcpy’d[] в строку
  2. перейдите к другой части приложения
  3. затем преобразуйте строку обратно в uint64 через memcpy

У меня есть сериализованный символ[]. Однако, когда я превращаю его в строку, содержимое меняется:

 

    uint64_t a = 6232222100000000000;
    char key[sizeof(a)] = {0};
    std::memcpy(key, amp;a, sizeof(uint64_t));

    for (std::size_t i = 0; i < sizeof(uint64_t);   i)
    {
        std::cout << std::bitset<8>(key[i]);
    }
    std::cout << "n";


    std::string out(key);
    for (std::size_t i = 0; i < sizeof(uint64_t);   i)
    {
        std::cout << std::bitset<8>(out[i]);
    }
  

Выводимые значения являются:

 0000000011001000110101101110111111111010010011000111110100000000
0000000000011101010000000000000000000000000000000000000000000000
  

Я не уверен, что происходит не так

Комментарии:

1. Тег C удален. Пожалуйста, обратите внимание, что C и C — это разные языки.

2. больше не повторю этой ошибки!

3. Если это присваивание, то оно довольно плохое … в принципе, вы не должны преобразовывать указатель int или массив в другой размер и использовать его как другой тип; даже если вы избегаете нарушения правил псевдонимирования и преобразования, это будет неприятно пахнуть.

4. Нет никакой гарантии, что key это допустимая строка, и если данные содержат , они завершатся досрочно, а если нет, то доступ к данным выйдет за пределы key . Если вы хотите поместить данные во std что-то, std::array или std::vector — лучший выбор.

Ответ №1:

Некоторые байты в uint64_t равны 0, поэтому они будут обрабатываться как нулевые терминаторы при преобразовании char[] массива в std::string с помощью std::string(const char*) конструктора, который ожидает указатель на массив символов с нулевым завершением в качестве входных данных. Таким образом, это приведет к усечению ваших char данных.

Затем ваш for цикл после преобразования выходит за пределы преобразованного std::string , вызывая неопределенное поведение.

Чтобы избежать этого, вам необходимо указать полный размер char[] массива во время преобразования в std::string :

 std::string out(key, sizeof(key));
  

Комментарии:

1. Для контекста это поисковая система, которая использует строки для десериализации ключей идентификатора запроса в пользовательский ключевой объект. Я добавляю функцию, которая выполняет расширение некоторых ключей в другие сопоставленные ключи. Примет, когда это позволит мне

2. Если у вас есть компилятор c 20, вы могли бы использовать key = std::bitcast<decltype(key)>(a); также приведение к новой интерпретации, или объединение может выполнить эту работу, но и то, и другое немного грязно.