Я сериализую данные в vector
из uint8_t
, чтобы отправить их в другой модуль. У меня есть строка, которую она вернула из функции getVal()
, и когда я это делаю vector.insert()
, в моем векторе больше отображаются случайные значения.
std::string getVal()
{
std::string x = "564";
return x ;
}
int main()
{
std::vector<uint8_t> data {0x70};
data.insert(data.end(),getVal().begin(),getVal().end());
for (auto i:data)
std::cout << i <<std::endl;
std::cout<<data.size()<<std::endl;
std::cout << getVal() <<" ,type: "<< sizeof(getVal()) << ", .size(): "<< getVal().size()<<std::endl;
return 0;
}
Ценю вашу помощь.
Решением было перебрать строку и использовать .push_back()
, но мне нужно понять, почему это произошло с .insert()
.
Примечание: ничто в этом коде не требует дополнительных вещей, которые делает std::endl
. Используйте '\n'
, чтобы завершить строку, если у вас нет веской причины не делать этого.
можешь прочитать о Pass parameters by Value vs pass parameters by referece
? Я думаю, вы получите больше информации о том, почему ваш код не работает, в частности, тип возвращаемого значения вызывает проблему.
Вероятно, вам все равно следует использовать std::transform , поскольку вы меняете типы данных (по крайней мере, для обозначения намерения). И еще есть std::back_inserter, который вы можете использовать вместо push_back.
Поскольку getVal
Возврат по значению, два вызова вернут два разных и несвязанных std::string
объекта.
Итераторы begin
и end
этих объектов будут связаны с разными объектами, и их совместное использование приведет к неопределенному поведению.
Либо вам нужно создать статическую строку и вернуть ссылку на нее. Или вам нужно сохранить строку, которую возвращает getVal
, и использовать этот объект.
Это потому, что вы вызываете begin()
и end()
, которые возвращают итератор (по сути, указатель на базовый массив) во временном объекте.
Вы возвращаете временный std::string
из функции getVal
.
Вот как вы можете это исправить:
std::string getVal() {
std::string x = "564";
return x; // note: Simpler is 'return "564";'
}
int main() {
std::vector<uint8_t> data { 'p' };
auto val = getVal(); // OK: Copy of the string.
data.insert(data.end(), val.begin(), val.end());
}
Использование временного не является проблемой; использование двух разных временных материалов.
Достаточно ясно, спасибо
Убедитесь, что у вас нет временной строки, и используйте std::transform и std::back_inserter следующим образом:
#include <algorithm>
#include <iterator>
#include <iostream>
#include <string>
#include <vector>
std::string getVal()
{
std::string x = "564";
return x ;
}
int main()
{
std::vector<uint8_t> data {0x70};
auto string = getVal();
std::transform(string.begin(),string.end(), std::back_inserter(data), [](const char c) { return static_cast<std::uint8_t>(c); });
for (const auto i:data)
std::cout << i << "\n";
return 0;
}
Можно использовать временный вариант (хотя это потребует некоторой гимнастики); проблема заключается в использовании двух разных временных протезов.
@PeteBecker Я хотел избежать упомянутой гимнастики;) Но да, я согласен с тем, что две разные гимнастики являются настоящей проблемой в вопросе ОП.
Достаточно ясно, спасибо
getVal().begin()
создает итератор в строке;getVal.end()
создает итератор в другую строку; два итератора не указывают на действительную последовательность.