Opened 15 years ago

Closed 15 years ago

#1086 closed Bugs (fixed)

Serialization of weak_ptr produces invalid XML

Reported by: anonymous Owned by: Robert Ramey
Milestone: To Be Determined Component: serialization
Version: Severity: Problem
Keywords: Cc:

Description

Hello, there seems to be a problem with serialization of weak_ptr.

The second example below produces invalid XML where the same attributes appears two times with different values. It appears that both save and load using boost::serialization works, but other tools complains about the XML being invalid. We don't know if this is a problem in Boost.Serialization or in Boost.Archive

The example has been tested using Boost 1.33.1 in Visual Studio 2005. We have not tested using Boost 1.34.0 yet.

Anders Edin, Sidec Technologies AB


#include <iostream>

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>

#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/weak_ptr.hpp>

class A
{
public:
    A() {}
    virtual ~A() {}

    virtual void set_self(boost::shared_ptr<A> s)
    {
        self_ = s;
    }

    virtual boost::shared_ptr<A> get_self() const
    {
        return self_.lock();
    }

private:
    friend boost::serialization::access;
    template <typename Archive>
    void serialize(Archive& archive, const unsigned int file_version)
    {
        archive & boost::serialization::make_nvp("self_", self_);
    }

    boost::weak_ptr<A> self_;
};

BOOST_CLASS_VERSION(A, 1);

class B: public A
{
public:
    B(): value_(3) {}
    virtual ~B() {}

private:    
    friend boost::serialization::access;
    template <typename Archive>
    void serialize(Archive& archive, const unsigned int file_version)
    {
        archive & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
        archive & boost::serialization::make_nvp("value_", value_);
    }

    int value_;
};

BOOST_CLASS_VERSION(B, 1);

int main(int argc, char* argv[])
{
    // This test object points to itself
    boost::shared_ptr<A> a(new A());
    a->set_self(a);

    // This test object also points to itself, but by pointing to its base class
    boost::shared_ptr<B> b(new B());
    b->set_self(b);

    // First example
    {
        boost::archive::xml_oarchive archive(std::cout);
        archive << boost::serialization::make_nvp("A", a);
    }

    std::cout<<std::endl;

    // Second example
    {
        boost::archive::xml_oarchive archive(std::cout);
        archive << boost::serialization::make_nvp("B", b);
    }

    return 0;
}

/* Output from running the program in Visual Studio 2005

-- The first example works as expected

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="3">
  <A class_id="0" tracking_level="0" version="1">
    <px class_id="1" tracking_level="1" version="1" object_id="_0">
      <self_ class_id="2" tracking_level="0" version="0">
        <px class_id_reference="1" object_id_reference="_0"></px>
      </self_>
    </px>
  </A>
</boost_serialization>

-- The second example produces invalid XML with attributes having two values in self_

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="3">
  <B class_id="0" tracking_level="0" version="1">
    <px class_id="1" tracking_level="1" version="1" object_id="_0">
      <A class_id="2" tracking_level="1" version="1" object_id="_1">
        <self_ class_id="3" tracking_level="0" version="0" class_id="4" tracking_level="0" version="1">
          <px class_id_reference="1" object_id_reference="_0"></px>
        </self_>
      </A>
      <value_>3</value_>
    </px>
  </B>
</boost_serialization>

*/

Change History (2)

comment:1 by Eric Niebler, 15 years ago

Owner: set to Robert Ramey

comment:2 by Robert Ramey, 15 years ago

Resolution: fixed
Status: newclosed

fixed by replacing tag name with "shared_ptr"

Note: See TracTickets for help on using tickets.