Boost logo

Boost :

From: martin.ecker_at_[hidden]
Date: 2004-05-07 07:57:39


Hello,

> I have difficulties when serializing two objects pointing to each
> other. The generated archive is fine (I can see both references in
> it), but when deserializing, only one is restored. In the attached
> example, I have a collection of nodes, each one is pointing to the
> previous and to the next node. When deserializing, only the ->next
> references are restored, all the ->previous are NULL.

I've stepped through your sample program in the debugger and found
that this is a bug in the boost::serialization library. The problem
lies in the following code from basic_archive_impl::load_pointer

    // if required
    if(track_object){
        // read data
        state_saver<bool> x(is_object);
        is_object = false;

        // predict next object id to be created
        object_id_type oid(object_id_vector.size());

        if(bis_ptr->tracking())
            object_id_vector.push_back(aobject(t, cid));

        // because the following operation could move the items
        // don't use co after this
        bisp_ptr->load_object_ptr(ar, t, co.file_version);
        assert(NULL != t);

        if(bis_ptr->tracking()){
            object_id_vector[oid].address = t;
            // and add to list of created pointers
            created_pointers.push_back(created_pointer_type(cid, t));
        }
    }

This block of code is executed when an object of a certain type
is deserialized through a pointer for the first time. This line

object_id_vector.push_back(aobject(t, cid));

registers the object ID as stored in the archive of the to-be-
deserialized object. If the same object ID is encountered later on in
the deserialization process a lookup is performed in object_id_vector
in order to retrieve a pointer to the previously deserialized object.
Note that t in the above line of code is a reference to the pointer
that will point to the object once it is deserialized. However, at the
time the above line is executed t is still a NULL pointer. The object
will be created in the call to load_object_ptr. In that call the
object will be created and deserialized from the archive. In your
sample application this will cause other objects to be deserialized
that have pointer member variables pointing to the same object t
points to, i.e. that have the same object ID. A lookup in
object_id_vector is performed to find the corresponding pointer to the
object and that pointer is used. But unfortunately, that pointer is
still NULL because only after the call to load_object_ptr will the
correct address be stored in the object_id_vector in this line of
code:

object_id_vector[oid].address = t;

However, this should happen immediately after space is allocated for
the object, i.e. immediately when the object's address is known and
_before_ the object is deserialized. I haven't looked any more into
it, but I hope it will be easy for Robert to fix.

Regards,
Martin

TAB Austria
Industrie- und Unterhaltungselektronik GmbH & CoKG
http://www.tab.at


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk