使用mmap序列化复杂对象
Serialize complex objetcs using mmap
我想在c++中使用mmap将一个复杂的对象序列化成二进制文件。我所说的复杂对象是指包含指针的对象(如树状数据结构)。
我们的想法是以后可以用mmap以这种方式从文件中加载对象:my_structure obj = (my_structure)mmap(...)
不需要重新加载所有的数据结构,出于性能的考虑(因为它是一个巨大的数据结构!)我在网上找到的所有例子都是非常简化的(比如如何在文件中放入一个int…),我没有找到任何关于如何写内存对应于一个包含指针的对象?我们怎样才能做到呢?
注意:我在mac osx上
我见过一种有趣的方法,但它的使用有些限制:
首先,您不能序列化指针或任何其他非POD类型。使用指针引用来序列化结构体的方法是使用一种特殊类型,它不保留指针值,而是保留指针值与其内存位置的偏移量:
的例子:
struct void_ptr
{
int offset;
void * get ()
{
return ((char*)this) + offset;
}
};
//or for generic type:
template <class T>
struct t_ptr
{
int offset;
T * get ()
{
return (T*)(((char*)this) + offset);
}
};
第二,你需要有一个特殊的序列化器来计算类/结构
中所有成员的偏移量。让我们举个例子,你想要序列化结构体A:
struct A
{
t_ptr<int> pointer_to_int;//let's suppose it points to an array of 2 ints
int my_value;
};
这个结构体的总内存需求是16字节或4个int(一个int用于my_value
,一个用于pointer_to_int
偏移,2个用于int数组指针指向的int指针)pointer_to_int
所指向的数组需要位于A结构内存数据之后的内存中,int_ptr
的偏移量应该是sizeof(A),因为
的例子:
int m[] = { 8, 1, 2, 3 };
A& a = *(A*)&m[0];
std::cout << a.my_value << std::endl;
std::cout << a.pointer_to_int.get()[0] << std::endl;
std::cout << a.pointer_to_int.get()[1] << std::endl;
在做这样的事情时,了解和处理内存对齐是非常重要的!!
你想做的事情在c++中是危险的。将指针或引用作为成员失败就足够了,因为在反序列化时将无法恢复它们。您将无法直接恢复指针,因为数据地址在运行之间会发生变化。
你很可能想要查看以下页面:
- 头儿原型
- msgpack
- Protocol Buffers
你可能还需要重构你的程序,这样,对于序列化的数据,你不使用指针作为成员,因为大多数库为你规定了一个合适的可序列化的数据结构:要么是他们自己生成的类,要么是普通数据和STL的组合。
根据数据的性质,您可能希望对数据进行分割或分组。
相关文章:
- Rapidjson 遍历并获取复杂 JSON 对象成员的值
- 当覆盖映射中的复杂对象键时,旧对象将被删除(C++)
- 是否可以保证输入<Type>实数时复杂对象的虚部设置为零?
- 如何查看复杂度为 O(1) 的字符串流对象中的最后一个字符
- 如何通过 COM 互操作访问复杂对象的属性?
- 将复杂对象从 C# 传递到C++
- 用于复杂对象的MPI共享内存
- 使用for_each打印复杂对象
- 如何初始化复杂对象的数组
- 如何使用复杂构造函数分配对象
- 避免在C++循环中循环中复杂对象时最小化范围效率低下的技术
- 将复杂对象传递给 c++ 中的函数,但数组订阅运算符无法正常工作
- 为复杂对象初始化选择哪种设计
- 如何在 gdb 中观察复杂对象
- 向QML公开复杂的Qt对象C++
- 如何使用数组通过引用对对象进行排序?(以一种不那么愚蠢/复杂的方式.)
- 在C++中保存复杂对象的方法
- 将二进制文件用于复杂对象C++
- 使用mmap序列化复杂对象
- 当一个std::vector对象在堆栈中而另一个在堆中时,vector的交换函数的时间复杂度为O(1)或O(n)