Boost logo

Boost Users :

Subject: [Boost-users] [Serialization / 1.58] wrong number of entries in std::vector<boost::tuple<double, double, double> >
From: Rüdiger Berlich (r.berlich_at_[hidden])
Date: 2015-04-18 10:38:12


Hi,

I’ve just installed Boost 1.58 and ran into the following problem: I have a class with a std::vector<boost::tuple<double, double, double> >, that is supposed to always have at least one entry, but may have more. Hence, in the default constructor, I initialize the std::vector with one entry. The class is also serializable. Up until Boost 1.57, a de-serialized object always had the correct number of entries in the vector. As of 1.58, I am getting one entry too much, which probably means that Boost.Serialization simply attaches entries to the vector of a default-constructed class, but doesn’t clear it first. This happens in C++11-Mode, both on Ubuntu 14.10 (gcc 4.9.1) as well as on MacOS X Yosemite . It DOES NOT happen with a std::vector<double> . Below is a full test case that replicates the problem in a simplified environment.

For Boost 1.57 the program returns:

t_vec.size() = 1
t_vec2.size() = 1

For Boost 1.58 the answer is

t_vec.size() = 1
t_vec2.size() = 2

Best Regards,
Beet

/******************************************************/

#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/tuple/tuple.hpp>

#include <iostream>
#include <vector>
#include <sstream>

namespace boost {
namespace serialization {

template<typename archive, typename T0, typename T1, typename T2>
void serialize(archive & ar, boost::tuple<T0, T1, T2> & tpl, unsigned int) {
 using namespace boost;
 using boost::serialization::make_nvp;

 ar
   & make_nvp("tpl_0", boost::get<0>(tpl))
   & make_nvp("tpl_1", boost::get<1>(tpl))
   & make_nvp("tpl_2", boost::get<2>(tpl));
}

} /* namespace serialization */
} /* namespace boost */

int main() {
 std::vector<boost::tuple<double, double, double> > t_vec, t_vec2(1);
 std::ostringstream oss;

 t_vec.push_back(boost::tuple<double, double, double>(1.,2.,3.));
 std::cout << "t_vec.size() = " << t_vec.size() << std::endl;

 // save data to archive
 {
   boost::archive::xml_oarchive oa(oss);
   // write class instance to archive
   oa & BOOST_SERIALIZATION_NVP(t_vec);
   // archive and stream closed when destructors are called
   // Data is now in oss
 }

 // load data from archive
 {
   std::istringstream iss(oss.str());
   boost::archive::xml_iarchive ia(iss);
   // read class state from archive
   ia & BOOST_SERIALIZATION_NVP(t_vec2);
   // archive and stream closed when destructors are called
 }

 std::cout << "t_vec2.size() = " << t_vec2.size() << std::endl;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net