Я уже давно пытаюсь заставить эту работу работать.
В моем проекте есть 6 классов, которые сериализуются с использованием точного учебника от boost, путем реализации функции шаблона сериализации.
Эти классы: State, guState, Policy, Action, Param, Vec3D.
Когда я сериализую и сохраняю их, все работает нормально.Я действительно получаю текстовый файл с различными номерами и строками.
Никаких жалоб, никаких предупреждений, никаких исключений.Единственный случай, когда я пытаюсь сериализовать указатель на член класса, процесс с дырой становится зомби.Поэтому я не пытаюсь сделать это, и сохранение работает.
Когда, однако, я пытаюсь загрузить, я получаю:
прекращение вызова после бросания экземпляра 'boost :: archive ::archive_exception 'what (): ошибка потока
Теперь интересная часть состоит в том, что я сериализовал два boost :: ptr_vectors, один, который состоит из указателей состояния, а другой - из указателей политики.
Вектор состояния я сохранил и загрузил без проблем.Вектор политики я могу сохранить, но когда я пытаюсь загрузить, я получаю исключение.
Кроме того, после прочтения руководств по повышению у меня сложилось впечатление, что для загрузки мне не нужно ничего, кромефункция serialize.
Однако, когда я попытался загрузить, boost serialization жаловался на то, что не нашел конструктор по умолчанию, такой как State (), Policy () и т. д. (я реализую свои собственные конструкторы в каждом классе).
После прочтения этого урока здесь Я реализовал конструктор по умолчанию, который ничего не делает, чтобы Boost-сериализация работала.Действительно, он скомпилировался, и я получил результаты, упомянутые выше.
Я попытался пойти по очень сложной дороге, которую видел в мой старый вопрос здесь , где я попытался разделить и реализовать save_construct_data и load_construct_dataно я нашел это слишком навязчивым, опять же я получил точную ошибку, как указано выше.
Может кто-нибудь, пожалуйста, помогите мне, объясните, как работает загрузка, как обстоят дела с конструкторами по умолчанию?Или, по крайней мере, укажите мне ссылку, которая может быть полезной.Я просмотрел инструкции в boost, и они мало что объясняют о реконструкции.
Спасибо.
Редактировать (Добавлено несколько фрагментов)
class State
{
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version);
protected:
std::map<std::string,float> positions;
float reward;
std::size_t hash_value;
bool exists(const Action* A);
bool operator== (State const& S);
std::size_t hash();
void clean_noise();
State(){}; // NOTE: This is used only by serializer, without it, code won't compile
public:
enum position { standing, on_chest, on_back, on_left, on_right, getting_up };
position current_position;
Policy *my_policy;
Vec3D gps;
boost::ptr_vector<Action> actions;
State(ACTION_MODE &m);
~State();
bool operator== (State const* S);
bool operator< (State const* S) const ;
const float& getR() const;
bool addAction(Action *A);
Action* findAction(const Action *A);
boost::ptr_vector<Action>& getAllActions();
void printState();
virtual bool isTerm();
};
template <class Archive>
void State::serialize(Archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(positions);
ar & BOOST_SERIALIZATION_NVP(gps);
ar & BOOST_SERIALIZATION_NVP(current_position);
ar & BOOST_SERIALIZATION_NVP(reward);
ar & BOOST_SERIALIZATION_NVP(hash_value);
ar & BOOST_SERIALIZATION_NVP(actions);
ar & BOOST_SERIALIZATION_NVP(my_policy);
}
ДругоеКлассы, наследующие от State, также имеют свои функции сериализации, используя:
ar & boost::serialization::base_object<State>(*this);
Class Policy:
class Policy
{
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version);
Policy() {}; // NOTE: Again same as with state, used only by serialize load
protected:
float QValue;
State *state;
public:
//! Base class constructor
Policy(State *s);
...
};
template <class Archive>
void Policy::serialize(Archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(action);
ar & BOOST_SERIALIZATION_NVP(state);
ar & BOOST_SERIALIZATION_NVP(QValue);
ar & BOOST_SERIALIZATION_NVP(r);
}
Как вы видите, это два основных класса, Другие классы также сериализуются.из-за зависимостей восстановления (класс Action, класс Param и т. д.)
Мастер-класс:
template <class S, class P> class Task
{
protected:
...
//! Container of states of type S (template parameter)
boost::ptr_vector<S> states;
//! Container of policies of type P (template parameter)
boost::ptr_vector<P> policies;
...
public:
Task(Agent &a, ACTION_MODE &m);
...
void save_to_file();
void load_from_file(std::string filename);
};
template <class S, class P>
void Task<S,P>::save_to_file()
{
std::string output = ramdisk+"serialized";
char *file = (char*)output.c_str();
std::ofstream ofs(file);
assert(ofs.good());
boost::archive::text_oarchive oa(ofs);
oa << states;
oa << policies;
ofs.close();
}
template <class S, class P>
void Task<S,P>::load_from_file(std::string filename)
{
char *file = (char*)output.c_str();
std::cout << file << std::endl;
std::ifstream ifs(file);
boost::archive::text_iarchive ia(ifs);
ia >> states;
ia >> policies;
ifs.close();
}
Эффективно содержит два boost :: ptr_vectors, в которых хранятся состояния и политики.Состояния сохраняются и загружаются без проблем.
Проблема возникает при загрузке политик.Сохранение их, похоже, не создает проблемы (но, опять же, я могу ошибаться).
Протестировав сохранение / загрузку без политик и с помощью, проблема, похоже, связана с реконструкцией политики.
Обратите внимание на конструкторы по умолчанию, используемые только для сериализации, без которой код не будет компилироваться.
РЕДАКТИРОВАТЬ # 2: После запуска приложения с использованием valgrind и memcheck, он сообщает, что имеется утечка памяти указателя.Однако, поскольку я не очень хорош в отладке с помощью valgrind, я не могу точно сказать, где происходит утечка или имеет ли она отношение к моей сериализации (я так думаю).