gpt4 book ai didi

c++ - 通过直接转换为 char 数组来序列化 POD 数据是否安全?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:37:49 26 4
gpt4 key购买 nike

假设 T 是一个不包含指针的 POD 类型,我想序列化 T(除了一些其他数据之外)。我创建了以下函数来执行此操作:

template<class T> void serialize(const T& source, char*& dest)
{
*(T*)dest = source;
dest += sizeof(T);
}
template<class T> void deserialize(T& dest, char*& source)
{
dest = *(T*)source;
source += sizeof(T);
}

这会导致任何问题吗,或者是否有任何编译器无法正常工作?换句话说,代码将:

template<class T> bool check_sanity(const T& obj)
{
std::unique_ptr<char[]> buffer { new int[sizeof(T)] };
serialize(obj, buffer);
T new_obj;
deserialize(new_obj, buffer);
return new_obj == obj;
}

有没有返回 false? (假设 T 是 POD 并且没有人重载 == 运算符)。

我正在编写这些序列化方法以与 MPI 结合使用,它们将在程序开始时用于分发簿记所需的一些数据,因此同一个程序将始终对数据进行序列化和反序列化.

最佳答案

我看到了几个问题。一个小的:

*(T*)dest = source;

IIRC,这是 UB,因为违反了别名规则(char * 可以别名任何其他指针,但这意味着您可以通过 char * 访问某些对象指针,但反之亦然,如您的示例所示)。

In other words, will the code: ... Ever return false?

可能不是,但您提到序列化的不仅仅是单个对象。

所以,主要问题是对齐:

std::unique_ptr<char[]> buffer { new char[sizeof(int) + 1] };
char x = 0;
int y = 0;
serialize(x, buffer);
serialize(y, buffer); // may crash or write into wrong location

故障线相同(但反序列化也受影响):

*(T*)dest = source; // source is int, dest is not aligned

编译器将假定 dest 已正确对齐并使用 CPU 指令进行对齐存储(在 ARM 架构上这将导致实际问题)。

解决方案是改用memcpy:

memcpy(dest, &source, sizeof(T));

无需担心性能。现代编译器能够很好地优化已知大小的对象的 memcpy。

关于c++ - 通过直接转换为 char 数组来序列化 POD 数据是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46625279/

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