повысить сериализацию динамических массивов

0

У меня код выглядит примерно так:

struct DataStruct
{
//  some fields here
};

class C1
{
public:
    C1(size_t n)
    {
        ptrData = new DataStruct[n];
        ptrPtrs = new DataStruct*[n];
        for(size_t i=0;i<n;i++)
            ptrPtrs[i] = &ptrData[i];
    }

    virtual ~C1() 
    {
        delete[] ptrData;
        delete[] ptrPtrs;
    }

    DataStruct* ptrData;
    DataStruct** ptrPtrs;
};

и нужно, чтобы он был сериализован, предпочтительно, с помощью boost :: serialization. Я не нашел способов сохранения динамически распределенных массивов, кроме сохранения его элемента по элементу в цикле. Но не уверен, как сохранить второй массив - массив указателей. Можно ли сделать это более или менее удобным способом в boost?

Теги:
arrays
serialization
boost
dynamic-arrays

1 ответ

2
Лучший ответ

Невозможно увеличить количество элементов, поскольку все, что у вас есть, - это указатель. Менеджер кучи знает, сколько элементов нужно удалить, когда вы вызываете delete [], но он не доступен для кода, например boost::serialize

Конечно, лучше всего использовать std::vector в первую очередь, но в противном случае создайте класс "обертка", который может использоваться для сериализации, как входящих, так и исходящих.

Если мы будем называть это ArrayWrapper и шаблоном,

template< typename T >
struct ArrayWrapper
{
   T* data = nullptr;
   size_t size = 0;
   ArrayWrapper() = default;
   ArrayWrapper( T* data_, size_t size_ ) : data( data_ ), size( size_ ) {}
};

Теперь вы можете сериализовать один из указателя и известного размера, сначала записав размер, затем каждый элемент.

При сериализации назад вы сначала читаете размер, затем выделяете количество объектов, а затем читаете их.

Конечно, вам нужно управлять своей памятью, а использование std::vector - гораздо лучший вариант.

В общем, вы не храните "указатели", в которых хранятся данные, на которые они указывают. при чтении обратно из архива вы не будете получать те же указатели, которые вошли, вы получите те же данные обратно.

Для этого вы фактически просто архивируете внешний (массив указателей) и получаете его для вызова ArrayWrapper на внутреннем.

  • 0
    ну, я надеялся, что у сериализации есть какой-то адаптер, позволяющий указать длину массива, как в моем ответе выше. вектор здесь не вариант, поскольку, насколько я помню, он не гарантирует, какие элементы не будут перемещаться внутри, поэтому невозможно хранить указатели на элементы вектора.
  • 0
    Ваши векторные элементы не будут перемещены, если вы не измените размер вашего вектора каким-либо образом, и если вы зарезервируете заранее, он никогда не будет перемещать их.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню