【问题标题】:exception: boost::archive::archive_exception at memory location异常:内存位置的 boost::archive::archive_exception
【发布时间】:2016-01-23 21:06:03
【问题描述】:

当我尝试反序列化二进制数据时,我得到这个:

异常:内存位置的 boost::archive::archive_exception

写:

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

阅读:

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

当我使用 text_iarchive \text_oarchive 工作正常。

序列化数据结构mData为ColorMatrix&lt;std::map&lt;int, float&gt;&gt;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

我在序列化步骤中发现了一个问题。有了测试数据就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;
}

【问题讨论】:

标签: c++ exception serialization boost deserialization


【解决方案1】:

两个提示

  • 确保档案的生命周期是关闭的,特别是不要重叠

  • 文本存档工作的事实让我想知道您是否正确地编写了二进制流。另请注意,您可以在 Boost Serialisation 中将多个档案安全地连接到同一个 Steam。

我有另一个答案,详细说明了这种情况以及它似乎如何适用于本网站的文本档案。

更新

查看代码后(谢谢!)我发现以下注释适用:

  1. 确实,在简单示例中,您无法明确管理存档对象的生命周期。我已经看到这会导致问题(在 MSVC IIRC 上)。您也可以在 [SO] 上找到它。所以,写:

    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. 您不使用std::ios::binary,这可能会产生影响(可能取决于平台):

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

我还建议改进ColorMatrix 类中字段和参数的命名。

【讨论】:

  • 感谢提示。我认为数据的问题。有什么问题- 尚不清楚。有测试数据一切OK。显然数据序列化工作是错误的。
  • 听起来很像“谢谢你的提示,我会放弃它们”。您没有显示代码来表明您没有这些问题。那么,你检查了吗?
  • 我已根据我的审核结果更新了答案(请参阅录制的实时编码会话:here (experiment))。查看结果代码:gist.github.com/sehe/98cc855478e9ab2a5388
  • 现在当我尝试读取时出现错误:“std::bad_alloc at memory location”。添加了测试代码。
猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 2021-05-03
  • 2015-04-13
  • 2019-11-21
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 2021-09-15
相关资源
最近更新 更多