exception: boost::archive::archive_exception at memory location

↘锁芯ラ 提交于 2020-01-03 19:40:42

问题


When I try to deserialize binary data I get this:

exception: boost::archive::archive_exception at memory location

write:

std::ofstream ofs(savePath);
boost::archive::binary_oarchive out_arch(ofs);
out_arch << mData;
ofs.close();

read:

std::ifstream ifs(loadPath);
boost::archive::binary_iarchive in_arch(ifs);
in_arch >> _mData;

When i use text_iarchive \text_oarchive work fine.

Serialized data structure mData is ColorMatrix<std::map<int, float>> mData;

#include <algorithm>
#include <memory>
#include <boost/serialization/vector.hpp>

template<class T, class A = std::allocator<T> >
struct ColorMatrix {
    typedef T value_type;
    typedef std::vector<value_type, A> Container;

    ColorMatrix() : _b(0) {}
    ColorMatrix(int a, int b, value_type const& initial = value_type())
        : _b(0)
    {
        resize(a, b, initial);
    }
    ColorMatrix(ColorMatrix const& other)
        : _data(other._data), _b(other._b)
    {}

    ColorMatrix& operator=(ColorMatrix copy) {
        swap(*this, copy);
        return *this;
    }

    bool empty() const { return _data.empty(); }
    void clear() { _data.clear(); _b = 0; }

    int dim_a() const { return _b ? _data.size() / _b : 0; }
    int dim_b() const { return _b; }

    value_type* operator[](int a) {
        return &_data[a * _b];
    }
    value_type const* operator[](int a) const {
        return &_data[a * _b];
    }

    void resize(int a, int b, value_type const& initial = value_type()) {
        if (a == 0) {
            b = 0;
        }
        _data.resize(a * b, initial);
        _b = b;
    }

    void copyTo(ColorMatrix<T, A> &other){

        int myA = dim_a();
        int myB = dim_b();
        int otherB = other.dim_b();

        for (int line = 0; line < myA; ++line){
            int myStart = line * myB;
            int myEnd = (line + 1) * myB;
            int otherStart = line*otherB;

            std::cout << "Line: " << line << " S1: " << myStart << " E1: " << myEnd << " S2: " << otherStart << std::endl;

            std::copy(_data.begin() + myStart,
                _data.begin() + myEnd,
                other._data.begin() + otherStart);
        }
    }

    friend void swap(ColorMatrix& a, ColorMatrix& b) {
        using std::swap;
        swap(a._data, b._data);
        swap(a._b, b._b);
    }


private:
    Container _data;
    int _b;

    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & _data;
        ar & _b;
    }
};

UPD1

I found a problem in the serialization step. With test data all ok.

Test code where all ok:

#include <iostream>
#include <vector>
#include <math.h>
#include <fstream>
#include <map>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/map.hpp>
#include "ColorMatrix.h"

using namespace std;

int main()
{
    cout << "start program" << endl;
    ColorMatrix<std::map<int, float>> mData;
    ColorMatrix<std::map<int, float>> mData2;

    const int mSize = 200;

    mData.resize(mSize, mSize);

    cout << "init" << endl;
    for (int x = 0; x < mSize; x++){
        for (int y = 0; y < mSize; y++){
            if (y % 2 == 0){
                mData[x][y][0] = 1.f;
                mData[x][y][1] = 0.66666f;
            }
            else if (y % 3 == 0){
                mData[x][y][0] = 1.f;
                mData[x][y][1] = 0.1111111111f;
                mData[x][y][3] = 0.44444444f;
            }
            else{
                mData[x][y][0] = 1.f;
            }

        }
    }

    cout << "write data" << endl;
    std::ofstream ofs("data.dat");
    boost::archive::binary_oarchive out_arch(ofs);
    //boost::archive::text_oarchive out_arch(ofs);
    out_arch << mData;
    ofs.close();

    cout << "read data" << endl;
    std::ifstream ifs("data.dat");
    if (!ifs) {
        cout << "read error!" << endl;
        return 1;
    }

    boost::archive::binary_iarchive in_arch(ifs);
    //boost::archive::text_iarchive in_arch(ifs);
    in_arch >> mData2;
    cout << "complete" << endl;
    return 0;
}

回答1:


Two hints

  • make sure the lifetime of the archives are closed and specifically do not overlap

  • the fact that text archives work makes me wonder whether you are properly writing binary streams. Also note that you can not concatenate multiple archives to the same steam safely in Boost Serialisation.

I have another answer detailing precisely this situating and how it seems to work for text archives in this site.

UPDATE

After reviewing the code (thanks!) I found the following notes apply:

  1. indeed in the simple sample, you fail to manage the life of the archive objects explicitly. I've seen this lead to problems (on MSVC IIRC). You can also find it on [SO]. So, write:

    cout << "write data" << endl;
    {
        std::ofstream ofs("data.dat");
        boost::archive::binary_oarchive out_arch(ofs);
        //boost::archive::text_oarchive out_arch(ofs);
        out_arch << mData;
    }
    
    cout << "read data" << endl;
    {
        std::ifstream ifs("data.dat");
        if (!ifs) {
            cout << "read error!" << endl;
            return 1;
        }
    
        boost::archive::binary_iarchive in_arch(ifs);
        //boost::archive::text_iarchive in_arch(ifs);
        in_arch >> mData2;
    }
    
  2. you don't use std::ios::binary, this might have impact (perhaps depending on platform):

    std::ofstream ofs("data.dat", std::ios::binary);
    // ...
    std::ifstream ifs("data.dat", std::ios::binary);
    

I'd also suggest improving the naming of the fields and parameters in teh ColorMatrix class.



来源:https://stackoverflow.com/questions/33317403/exception-boostarchivearchive-exception-at-memory-location

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!