使用 std::array 时的输入流问题
Input stream problem when using std::array
当 struct A
中没有 bool b
时,代码有效。当 bool b
存在时,ar & mat
会给出“输入流错误”,但可以一个一个地注册 std::array
的元素。这里有什么问题?
#include <fstream>
#include <boost/serialization/array.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
struct A
{
std::array<int, 3> mat;
bool b;
template<class Archive> void serialize(Archive& ar, const unsigned int version)
{
//ar & mat[0];
//ar & mat[1];
//ar & mat[2];
ar & mat;
ar & b;
}
};
int main()
{
{
std::string fname = "save.sr";
std::ofstream ofs(fname);
boost::archive::text_oarchive oa(ofs);
A a;
oa << a;
}
{
std::string fname = "save.sr";
std::ifstream ifs(fname);
boost::archive::text_iarchive ia(ifs);
A a;
ia >> a;
}
return 0;
}
我没看出有什么问题。然后我查看 asan/ubsan 并发现域转换问题:http://coliru.stacked-crooked.com/a/edee75a22450d9ee
起初我以为特定版本的 Boost[¹] 中可能存在错误。然后我恍然大悟。
有良性警告:
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp -fsanitize=address,undefined -lboost_serialization && ./a.out
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct oserializer'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct iserializer'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct oserializer'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct iserializer'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
然后我们得到域错误:
/usr/local/include/boost/archive/text_oarchive.hpp:65:50: runtime error: load of value 255, which is not a valid value for type 'bool'
注意oarchive
是怎么碰到他们的,确认一下:
debug: "22 serialization::archive 17 0 0 0 0 3 -2049146224 32767 -2049145920 1
"
那些是...不确定的值。对于完整的整数域来说问题不大,但对于 bool 来说是个大问题。所以,修正你的初始化:
struct A {
std::array<int, 3> mat {};
bool b {};
template <class Ar> void serialize(Ar& ar, unsigned) {
ar & mat & b;
}
};
当然你也可以使用其他样式:
std::array<int, 3> mat = {0,0,0};
bool b = false;
或者老式的构造函数:
std::array<int, 3> mat;
bool b;
A(std::array<int, 3> mat = {}, bool b = {}) : mat(mat), b(b) {}
等只要您确保初始化您的会员数据。
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/array.hpp>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <boost/version.hpp>
struct A {
std::array<int, 3> mat = {0,0,0};
bool b = false;
template <class Ar> void serialize(Ar& ar, unsigned) {
ar & mat & b;
}
};
int main() {
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
A a;
oa << a;
}
std::cout << "BOOST_VERSION: " << BOOST_VERSION << "\n";
std::cout << "debug: " << std::quoted(ss.str()) << "\n";
{
boost::archive::text_iarchive ia(ss);
A a;
ia >> a;
}
}
版画
BOOST_VERSION: 107500
debug: "22 serialization::archive 18 0 0 0 0 3 0 0 0 0
"
[¹] 这就是徒劳无功的样子
- Wandbox Boost 1.73 no problem
- Wandbox Boost 1.72 no problem
- Wandbox Boost 1.71 only warnings
- Wandbox Boost 1.70 same warnings
- Wandbox Boost 1.69 same
- Wandbox Boost 1.68 no problem
- Wandbox Bosot 1.67 no problem
- Wanbox Boost 1.66 no problem
- Wandbox Boost 1.65.1 no problem
- 魔杖提升 1.65 no problem
- Wandbox Boost 1.64.0 no problem
- Wandbox Boost 1.63.0 no problem
- Wandbox Boost 1.62 no problem
- Wandbox Boost 1.61 no problem
- Wandbox Boost 1.60 no problem
当 struct A
中没有 bool b
时,代码有效。当 bool b
存在时,ar & mat
会给出“输入流错误”,但可以一个一个地注册 std::array
的元素。这里有什么问题?
#include <fstream>
#include <boost/serialization/array.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
struct A
{
std::array<int, 3> mat;
bool b;
template<class Archive> void serialize(Archive& ar, const unsigned int version)
{
//ar & mat[0];
//ar & mat[1];
//ar & mat[2];
ar & mat;
ar & b;
}
};
int main()
{
{
std::string fname = "save.sr";
std::ofstream ofs(fname);
boost::archive::text_oarchive oa(ofs);
A a;
oa << a;
}
{
std::string fname = "save.sr";
std::ifstream ifs(fname);
boost::archive::text_iarchive ia(ifs);
A a;
ia >> a;
}
return 0;
}
我没看出有什么问题。然后我查看 asan/ubsan 并发现域转换问题:http://coliru.stacked-crooked.com/a/edee75a22450d9ee
起初我以为特定版本的 Boost[¹] 中可能存在错误。然后我恍然大悟。
有良性警告:
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp -fsanitize=address,undefined -lboost_serialization && ./a.out
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct oserializer'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct iserializer'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct oserializer'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct iserializer'
/usr/local/include/boost/serialization/singleton.hpp:181:12: runtime error: reference binding to null pointer of type 'const struct extended_type_info_typeid'
然后我们得到域错误:
/usr/local/include/boost/archive/text_oarchive.hpp:65:50: runtime error: load of value 255, which is not a valid value for type 'bool'
注意oarchive
是怎么碰到他们的,确认一下:
debug: "22 serialization::archive 17 0 0 0 0 3 -2049146224 32767 -2049145920 1
"
那些是...不确定的值。对于完整的整数域来说问题不大,但对于 bool 来说是个大问题。所以,修正你的初始化:
struct A {
std::array<int, 3> mat {};
bool b {};
template <class Ar> void serialize(Ar& ar, unsigned) {
ar & mat & b;
}
};
当然你也可以使用其他样式:
std::array<int, 3> mat = {0,0,0};
bool b = false;
或者老式的构造函数:
std::array<int, 3> mat;
bool b;
A(std::array<int, 3> mat = {}, bool b = {}) : mat(mat), b(b) {}
等只要您确保初始化您的会员数据。
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/array.hpp>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <boost/version.hpp>
struct A {
std::array<int, 3> mat = {0,0,0};
bool b = false;
template <class Ar> void serialize(Ar& ar, unsigned) {
ar & mat & b;
}
};
int main() {
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
A a;
oa << a;
}
std::cout << "BOOST_VERSION: " << BOOST_VERSION << "\n";
std::cout << "debug: " << std::quoted(ss.str()) << "\n";
{
boost::archive::text_iarchive ia(ss);
A a;
ia >> a;
}
}
版画
BOOST_VERSION: 107500
debug: "22 serialization::archive 18 0 0 0 0 3 0 0 0 0
"
[¹] 这就是徒劳无功的样子
- Wandbox Boost 1.73 no problem
- Wandbox Boost 1.72 no problem
- Wandbox Boost 1.71 only warnings
- Wandbox Boost 1.70 same warnings
- Wandbox Boost 1.69 same
- Wandbox Boost 1.68 no problem
- Wandbox Bosot 1.67 no problem
- Wanbox Boost 1.66 no problem
- Wandbox Boost 1.65.1 no problem
- 魔杖提升 1.65 no problem
- Wandbox Boost 1.64.0 no problem
- Wandbox Boost 1.63.0 no problem
- Wandbox Boost 1.62 no problem
- Wandbox Boost 1.61 no problem
- Wandbox Boost 1.60 no problem