gpt4 book ai didi

c++ - C++ 中整数 vector 的序列化/反序列化

转载 作者:行者123 更新时间:2023-11-28 01:31:47 31 4
gpt4 key购买 nike

要完成的任务

我正在尝试将一个整数 vector 序列化为一个字符串,以便将其存储到一个文件中。使用的方法是将整数逐字节复制到缓冲区中。为此,我使用了 std::copy_n 函数。

为了反序列化,我做了同样的事情,即从缓冲区逐字节复制到一个整数,并将这些整数附加到一个 vector 。

我不确定这是否是实现此目标的最佳/最快方法。

代码

序列化函数

char *serialize(vector <int> nums)
{
char *buffer = (char *)malloc(sizeof(int)*nums.size());
vector <int>::iterator i;
int j;
for(i = nums.begin(), j = 0; i != nums.end(); i++, j += 4) {
copy_n(i, 4, buffer+j);
}
return buffer;
}

反序列化函数

vector <int> deserialize(char *str, int len)
{
int num;
vector <int> ret;
for(int j = 0; j < len; j+=4) {
copy_n(str+j, 4, &num);
ret.push_back(num);
}
return ret;
}

任何关于如何改进这段代码的意见都会非常有帮助。我也很想知道实现相同目标的其他方法。

最佳答案

你的方法有很多问题。

char *serialize(vector <int> nums)
{
char *buffer = (char *)malloc(sizeof(int)*nums.size());
vector <int>::iterator i;
int j;
for(i = nums.begin(), j = 0; i != nums.end(); i++, j += 4) {
copy_n(i, 4, buffer+j);
}
return buffer;
}

1) 它手动分配内存,这是危险的并且很少需要。

2) 它并不像您想象的那样。它从字面上复制每个 int 并尝试将其填充到 char 中。因此,如果任何值超过 255(可填充到 char 中的最大数量),数据就会损坏。

如果您正在寻找效率,那么我认为最好的方法是将数据直接写入输出流,而不是先将其转换为字符串。

请记住,像这样写出二进制数据不可移植的。我只会用它来序列化/反序列化本地数据。理想情况下来自单个 session 。除此之外,您必须开始考虑让每个输出数据都可移植,这会变得更加复杂。除非绝对必要,否则我个人会完全避免二元方法。

如果你必须这样做,我可能会做更多类似的事情:

template<typename POD>
std::ostream& serialize(std::ostream& os, std::vector<POD> const& v)
{
// this only works on built in data types (PODs)
static_assert(std::is_trivial<POD>::value && std::is_standard_layout<POD>::value,
"Can only serialize POD types with this function");

auto size = v.size();
os.write(reinterpret_cast<char const*>(&size), sizeof(size));
os.write(reinterpret_cast<char const*>(v.data()), v.size() * sizeof(POD));
return os;
}

template<typename POD>
std::istream& deserialize(std::istream& is, std::vector<POD>& v)
{
static_assert(std::is_trivial<POD>::value && std::is_standard_layout<POD>::value,
"Can only deserialize POD types with this function");

decltype(v.size()) size;
is.read(reinterpret_cast<char*>(&size), sizeof(size));
v.resize(size);
is.read(reinterpret_cast<char*>(v.data()), v.size() * sizeof(POD));
return is;
}

这些函数的接口(interface)遵循标准库中的约定,它足够灵活,您可以使用它序列化为文件(使用 std::fstream)或字符串(使用 std::stringstream).

std::vector<int> v = {1, 2, 3, 500, 900};

std::stringstream oss; // this could just as well be a `std::fstream`

if(serialize(oss, v))
{
std::vector<int> n;
if(deserialize(oss, n))
{
for(auto i: n)
std::cout << i << '\n';
}
}

输出:

1
2
3
500
900

关于c++ - C++ 中整数 vector 的序列化/反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51230764/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com