Как указать связи между указателями и исходными данными?

260
19 декабря 2016, 19:44

При сериализации в boost::serialization можно записать вектор std::vector<int> base;

И затем восстановить его. Можно записать указатель на этот вектор и так же восстановить. Можно записать std::vector<int*> base вектор с указателями и так же восстановить по значению.

Но как сделать(если можно), чтобы при сериализации сохранялись связи между исходными данными и указателями на них.

То есть чтобы при восстановлении

std::vector<int> <<------------------------------------------\
                                                             |
в контейнере `std::vector<int*>` хранились указатели на ---> |

Это можно сделать и вручную, но интересуют именно возможности boost.

#include <boost/iostreams/stream.hpp> 
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/serialization/array.hpp> 
#include <boost/serialization/string.hpp> 
#include <boost/serialization/vector.hpp>
#include <boost/archive/xml_oarchive.hpp> 
#include <boost/archive/xml_iarchive.hpp> 
#include <boost/serialization/export.hpp> 
#include <iostream> 
#include <fstream>
int main()
{
std::system("chcp 1251");
// Исходные данные
std::vector<int> base;
base.push_back(77);
// вот здесь хранятся указатели на base
std::vector<int*> links;
links.push_back(&base[0]);
/// Здесь запись и востановление base
//
{
std::ofstream OA("file.txt");
std::cout << "\nдо base[0]=" << base[0];
boost::archive::xml_oarchive oa(OA);
oa << BOOST_SERIALIZATION_NVP(base);
}
// очистка
base.clear();
{
std::ifstream IA("file.txt");
boost::archive::xml_iarchive ia(IA);
ia >> BOOST_SERIALIZATION_NVP(base);
std::cout << "\nпосле base[0]=" << base[0];
}
#ifdef здесь_ошибка_компиляции 
// error C2228: выражение слева от ".serialize" должно представлять класс, структуру или объединение
/// Здесь запись и востановление links
//
{
std::ofstream OA("file.txt");
std::cout << "\nдо base[0]=" << links[0];
boost::archive::xml_oarchive oa(OA);
oa << BOOST_SERIALIZATION_NVP(links);
}
// очистка
links.clear();
{
std::ifstream IA("file.txt");
boost::archive::xml_iarchive ia(IA);
ia >> BOOST_SERIALIZATION_NVP(links);
std::cout << "\nпосле base[0]=" << links[0];
}
#endif
Answer 1

Во-первых, крайне нежелательно работать с указателями на объекты в std::vector, потому что он не гарантирует, что данные не будут перемещены в памяти во время работы программы. Ваши указатели окажутся сломанными, и программа упадет или натворит бед. Вместо этого используйте std::list, он гарантированно не сломает ваши указатели.

Во-вторых, сначала загрузить массив, а потом создать массив с ссылками на него — нетипичная ситуация, и скорее всего она в Boost не реализована. Лучше и безопаснее будет реализовать это вручную.

И прежде чем доверять Бусту работать с указателями, подумайте, кто будет чистить память. Если вы загружаете из файла данные в виде указателей, то их придется вычищать вручную.

READ ALSO
Произвольное чтение из файла

Произвольное чтение из файла

Например есть файл размером 1ГБ, как получить участок данных из него находящиеся где то посередине не читая его полностью

280
Утечки памяти в OpenCV

Утечки памяти в OpenCV

У меня в проекте есть такие строчки кода(с++):

290
Как скомпилировать release в Qt Creator?

Как скомпилировать release в Qt Creator?

Не могу понять, как скомпилировать realease, что бы приложением можно было свободно пользоваться и оно не требовало библиотек Qt

286
В чем отличие Windows Forms Application C++ и C#

В чем отличие Windows Forms Application C++ и C#

В чем отличие Windows Forms Application C++ и C#

305