Я представляю базовые блоки кода и поток управления между ними как циклический граф и хочу иметь возможность сериализовать график на XML или аналогичный, а затем десериализировать его и использовать график в другое приложение. При попытке сериализации структуры данных я получаю тысячи вызовов функции сериализации, хотя граф, который я использую для тестирования приложения, содержит менее пятидесяти узлов, что заставляет меня думать, что проблема связана с циклическими ссылками.Сериализовать циклические графики с BOOST в C++
Когда я запускаю или отлаживает приложение, он успешно повторно вводит функцию void serialize(Archive&, std::vector<BasicBlock*>&, const unsigned)
, пока не сработает с ошибкой сегментации. Выходной файл создается, но на него ничего не записывается.
Ниже приведена структура данных, которую я использую для представления основных блоков;
struct __attribute__ ((visibility ("default"))) BasicBlock {
unsigned int id;
unsigned int start_address;
unsigned int end_address;
std::vector<BasicBlock*>* outgoing;
std::vector<BasicBlock*>* incoming;
};
и это класс сериализации и функции
class Serialize {
public:
static void marshal(const std::vector<BasicBlock*>& basic_blocks, std::string filename) {
std::ofstream ofstream(filename.c_str(), std::ios::out | std::ios::binary);
boost::archive::text_oarchive archive(ofstream);
archive << basic_blocks;
}
static void unmarshal(const std::string filename, std::vector<BasicBlock*>& basic_blocks) {
std::ifstream ifstream(filename.c_str());
boost::archive::text_iarchive archive(ifstream);
archive >> basic_blocks;
}
};
namespace boost {
namespace serialization {
template<class Archive>
void save(Archive & archive, const BasicBlock& basic_block, const unsigned int version) {
archive & basic_block.id;
archive & basic_block.start_address;
archive & basic_block.end_address;
archive & basic_block.incoming;
archive & basic_block.outgoing;
}
template<class Archive>
void load(Archive & archive, BasicBlock& basic_block, const unsigned int version) {
archive & basic_block.id;
archive & basic_block.start_address;
archive & basic_block.end_address;
archive & basic_block.incoming;
archive & basic_block.outgoing;
}
template<typename Archive>
void serialize(Archive& archive, std::vector<BasicBlock>& basic_blocks, const unsigned version) {
archive & basic_blocks;
}
template<typename Archive>
void serialize(Archive& archive, std::vector<BasicBlock*>& basic_blocks, const unsigned version) {
archive & basic_blocks; // Triggered thousands of times...
}
}
}
BOOST_SERIALIZATION_SPLIT_FREE(BasicBlock)
Вы были правы, спасибо так много. Это становится немного проблематичным, когда вы (я) включаете огромную структуру в проект и просто принимаете все волшебные вещи, которые внезапно предоставляются. Не думайте, что я когда-либо выяснял, что это был рекурсивный вызов сам по себе. –