Hi,
Ivan Rachev wrote:
Does anyone have an idea how to serialize dynamic arrays of objects?
An example follows at the end.
Please post fully working examples. That will make it easier for people to help
you. Your example requires a file test.txt that you didn't send along in your
e-mail.
Its weakness shows up when an outside
pointer points to an element in the array. The problem is that the type
being serialized is T but not T*.
This should actually work fine. I modified your sample to use a memory buffer
instead of a file and added an assert to make sure the deserialized
second-element pointer points to the correct element. The assert does
not trigger with MSVC 7.1.
#include <sstream>
#include
#include
#include
#include
class A
{ friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {}
};
//IVAN Element always points to the beginning of an array of
// 'Size' elements. The array is NOT null-terminated. If
// size == 0, Elements may hold an undefined value. User
// is responsible for initializing, new-ing and delete-ing.
// Assumption: if there is an outside pointer to an object
// inside this array, after loading the array
// that pointer will hold a different object.
template <typename T>
struct DynamicArray
{
int Size;
T* Element;
friend class boost::serialization::access;
template<class Archive>
void save(Archive & ar, const unsigned int version) const
{
ar & Size;
for (int i = 0; i < Size; ++i)
ar & Element[i];
}
template<class Archive>
void load(Archive & ar, const unsigned int version)
{
ar & Size;
//TODO: assert(Size >=0);
if (Size > 0)
{
Element = new T[Size];
for (int i = 0; i < Size; ++i)
ar & Element[i];
}
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
int main(int argc, char* argv[])
{
DynamicArray<A> ArrayOfAs, ArrayOfAs2;
ArrayOfAs.Element = new A[5];
ArrayOfAs.Size = 5;
A* secondElement = &ArrayOfAs.Element[1];
A* secondElement2;
std::stringstream stream;
{
boost::archive::text_oarchive oa(stream);
oa & ArrayOfAs;
oa & secondElement; // this guy will point to a copy of the
// 2nd element but NOT the 2nd element itself
}
{
boost::archive::text_iarchive ia(stream);
ia & ArrayOfAs2;
ia & secondElement2; // this guy will point to a copy of the
// 2nd element but NOT the 2nd element itself
}
// does not trigger, so the above should work
assert(secondElement2 == &ArrayOfAs2.Element[1]);
delete [] ArrayOfAs.Element;
delete [] ArrayOfAs2.Element;
}
Best Regards,
Martin