#c
#c
Вопрос:
Мне нужно:
- преобразуйте символ uint64 memcpy’d[] в строку
- перейдите к другой части приложения
- затем преобразуйте строку обратно в 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);
также приведение к новой интерпретации, или объединение может выполнить эту работу, но и то, и другое немного грязно.