1 | #include <iostream>
|
---|
2 | #include <vector>
|
---|
3 | #include <fstream>
|
---|
4 | #include <cassert>
|
---|
5 |
|
---|
6 | #include <boost/serialization/vector.hpp>
|
---|
7 | #include <boost/archive/xml_oarchive.hpp>
|
---|
8 | #include <boost/archive/xml_iarchive.hpp>
|
---|
9 |
|
---|
10 | struct dummy {
|
---|
11 | template<class Archive>
|
---|
12 | void serialize(Archive& ar, unsigned int version) {}
|
---|
13 | };
|
---|
14 |
|
---|
15 | int main() {
|
---|
16 | // One-level container
|
---|
17 | // For comparison only. This shows the expected behaviour.
|
---|
18 | {
|
---|
19 | // Create a dummy object in a vector
|
---|
20 | std::vector<dummy> l(1);
|
---|
21 |
|
---|
22 | // Let pd point to that dummy object
|
---|
23 | dummy* pd = &l.back();
|
---|
24 |
|
---|
25 | // Serialize and deserialize the vector and the pointer
|
---|
26 | // Here, the order is important: We have to (de)serialize the vector first,
|
---|
27 | // otherwise we run into an issue similar to what is described at
|
---|
28 | // http://www.boost.org/doc/libs/1_57_0/libs/serialization/doc/exceptions.html#pointer_conflict
|
---|
29 | {
|
---|
30 | std::ofstream ofs("one_level.xml");
|
---|
31 | boost::archive::xml_oarchive oa(ofs);
|
---|
32 | oa << BOOST_SERIALIZATION_NVP(l) << BOOST_SERIALIZATION_NVP(pd);
|
---|
33 | }
|
---|
34 | {
|
---|
35 | std::ifstream ifs("one_level.xml");
|
---|
36 | boost::archive::xml_iarchive ia(ifs);
|
---|
37 | ia >> BOOST_SERIALIZATION_NVP(l) >> BOOST_SERIALIZATION_NVP(pd);
|
---|
38 | }
|
---|
39 |
|
---|
40 | // Thanks to address tracking, pd still points to the dummy object,
|
---|
41 | // even if the latter is loaded at a different address.
|
---|
42 | assert(&l.back() == pd); // Does not fire
|
---|
43 | }
|
---|
44 |
|
---|
45 | std::cout << std::endl;
|
---|
46 |
|
---|
47 | // Two-level container
|
---|
48 | // This is buggy.
|
---|
49 | {
|
---|
50 | // Create a dummy object in a *nested* vector
|
---|
51 | std::vector<std::vector<dummy>> l(1, std::vector<dummy>(1));
|
---|
52 |
|
---|
53 | // Again, let pd point to the dummy object
|
---|
54 | dummy* pd = &l.back().back();
|
---|
55 |
|
---|
56 | // Same as before...
|
---|
57 | {
|
---|
58 | std::ofstream ofs("two_level.xml");
|
---|
59 | boost::archive::xml_oarchive oa(ofs);
|
---|
60 | oa << BOOST_SERIALIZATION_NVP(l) << BOOST_SERIALIZATION_NVP(pd);
|
---|
61 | }
|
---|
62 | {
|
---|
63 | std::ifstream ifs("two_level.xml");
|
---|
64 | boost::archive::xml_iarchive ia(ifs);
|
---|
65 | ia >> BOOST_SERIALIZATION_NVP(l) >> BOOST_SERIALIZATION_NVP(pd);
|
---|
66 | }
|
---|
67 |
|
---|
68 | // Again, we would like pd to point to the dummy object, independent
|
---|
69 | // of where it is loaded. This is not the case, however.
|
---|
70 | assert(&l.back().back() == pd); // Does fire!!!
|
---|
71 | }
|
---|
72 |
|
---|
73 | return 0;
|
---|
74 | }
|
---|
75 |
|
---|