boost::serialization について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
thaz

boost::serialization について

#1

投稿記事 by thaz » 13年前

1.クラスAはメンバとしてstd::mapをもつ。
2.クラスBはメンバとして「クラスAを要素型とするstd::vector」をもつ。
3.このクラスBをserializeしてバイナリファイルとして出力する。
4.書き出したバイナリファイルを読み込むとハンドルされていない例外が発生する。

なにか原因についてご指摘をして頂ければと思います。

int main() {
A a ;
B b ;
////////// 繰り返し ////////////////////
aのstd::mapにデータを格納
b.push_back( a ) ;
//////////////////////////////////////
std::ofstream ofs( "dataFile.dat" ) ;
boost::archive::binary_oarchive oa( ofs ) ;
oa << b ;
ofs.close() ;

B bb ;

std::ifstream ifs( "dataFile.dat" ) ;
boost::archive::binary_iarchive ia( ifs ) ;
ia >> bb ; ←ここで落ちます。
ifs.close() ;
}

アバター
結城
記事: 52
登録日時: 14年前
連絡を取る:

Re: boost::serialization について

#2

投稿記事 by 結城 » 13年前

パッと見て推測でしかないのですが

クラスAはstd::mapを
クラスBはstd::vector<A>をそれぞれメンバとして保持しているようなので
以下のような原因が考えられます。

std::map型及びstd::vector型は配列を保持する際
自動的にメモリ領域を取得し、そのサイズを広げます。
したがって、初期のサイズは 0 です

シリアライズしたデータを
ia >> bb
で代入していますが
bbのメンバであるvector型はおそらくサイズがゼロであるため
出力したデータと容量が食い違い、受け入れる事が出来ないのではないでしょうか?
ANGE;ART

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: boost::serialization について

#3

投稿記事 by h2so5 » 13年前

クラスA, B の定義を具体的に書いてほしいです。

thaz

Re: boost::serialization について

#4

投稿記事 by thaz » 13年前

クラス定義は以下の通りです。

<< Hinari 様
   ご指摘の事を試してみました。出力元のインスタンス b に対して ia >> b としても
   同じエラーで落ちました。

class A {
private :
friend class boost::serialization::access ;
template< class Archive >
void serialize( Archive& ar, const unsigned int version ) {
ar & mMap ;
}
public:
ClassData(void);
~ClassData(void);
std::map< std::string, int > mMap ;
} ;

class B {
private :
friend class boost::serialization::access ;
template< class Archive >
void serialize( Archive& ar, const unsigned int version ) {
ar & mVector ;
}
public :
AllClassData(void);
~AllClassData(void);
std::vector< A > mVector ;
} ;

アバター
結城
記事: 52
登録日時: 14年前
連絡を取る:

Re: boost::serialization について

#5

投稿記事 by 結城 » 13年前

<< thazさん
[tab=30]コードを書くときはコードタグで囲むようにしてくださいね
[tab=30]

コード:

[code=cpp]
[/code]で囲むとおkです。

[tab=30]あとインデントも大事です。

ところで、こちらはインクルードされたでしょうか?
boostにてvectorおよびmapを使用する際には

コード:

#include <boost/serialization/vector.hpp>
#include <boost/serialization/map.hpp>
が必要なようです
ANGE;ART

thaz

Re: boost::serialization について

#6

投稿記事 by thaz » 13年前

>> 結城(元:Hinari) 様

 コメントありがとうございます。boost関連のインクルードは以下のものをしています。

#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/map.hpp>

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: boost::serialization について

#7

投稿記事 by h2so5 » 13年前

私の環境では正常に実行されました。

Windows Vista
MinGW gcc4.6.2
Boost 1.49.0

コード:

#include <vector>
#include <map>

#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/map.hpp>

class A {
    private:
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive& ar, const unsigned int version)
        {
            ar & mMap;
        }
    public:
        std::map<std::string, int> mMap;
};

class B {
    private:
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive& ar, const unsigned int version)
        {
            ar & mVector;
        }
    public:
        std::vector<A> mVector;
};

int main()
{
    A a;
    B b;

    a.mMap["foo"] = 100;
    b.mVector.push_back(a);

    std::ofstream ofs("dataFile.dat");
    boost::archive::binary_oarchive oa(ofs);
    oa << b;
    ofs.close();

    B bb;

    std::ifstream ifs("dataFile.dat");
    boost::archive::binary_iarchive ia(ifs);
    ia >> bb; // ←ここで落ちます。
    ifs.close();
}

thaz

Re: boost::serialization について

#8

投稿記事 by thaz » 13年前

すみません。
色々と試した結果、以下のコードが最小コードかと思うのですが、どうでしょうか?
最後の ia >> b で落ちます。

コード:

#include <vector>
#include <map>
#include <string>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/map.hpp>

class A {
private :
	friend class boost::serialization::access ;
	template< class Archive >
		void serialize( Archive& ar, const unsigned int version ) {
			ar & mMap ;
		}
public :
	ClassData(void) ;
	~ClassData(void) ;
	std::map< int, long int > mMap ;
} ;

class AllClassData {
private :
	friend class boost::serialization::access ;
	template< class Archive >
		void serialize( Archive& ar, const unsigned int version ) {
			ar & mVector ;
		}
public :
	AllClassData(void) ;
	~AllClassData(void) ;
	std::vector< A > mVector ;
} ;

int main() {
	A a ;
	B b ;
	for ( int i = 1 ; i < 100 ; i ++ ) {
		a.mMap[ i ] = 99 ;
	}
	b.mVector.push_back( a ) ;
	std::ofstream ofs( "data.dat" ) ;
	boost::archive::binary_oarchive oa( ofs ) ;
	oa << b ;
	ofs.close() ;

	std::ifstream ifs( "data.dat" ) ;
	boost::archive::binary_iarchive ia( ifs ) ;
	ia >> b ;
	ifs.close() ;
	return 0 ;
}

thaz

Re: boost::serialization について

#9

投稿記事 by thaz » 13年前

度々すみません。コードに誤りがあったので訂正します。
宜しくお願い致します。最後の ia >> b で落ちます。

コード:

#include <fstream>
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/map.hpp>
 
class A {
private :
    friend class boost::serialization::access ;
    template< class Archive >
        void serialize( Archive& ar, const unsigned int version ) {
            ar & mMap ;
        }
public :
	A(void) {};
	~A(void) {};
    std::map< int, long int > mMap ;
} ;
 
class B {
private :
    friend class boost::serialization::access ;
    template< class Archive >
        void serialize( Archive& ar, const unsigned int version ) {
            ar & mVector ;
        }
public :
	B(void) {};
	~B(void) {};
    std::vector< A > mVector ;
} ;
 
int main() {
    A a ;
    B b ;
    for ( int i = 1 ; i < 100 ; i ++ ) {
        a.mMap[ i ] = 99 ;
    }
    b.mVector.push_back( a ) ;
    std::ofstream ofs( "data.dat" ) ;
    boost::archive::binary_oarchive oa( ofs ) ;
    oa << b ;
    ofs.close() ;
 
    std::ifstream ifs( "data.dat" ) ;
    boost::archive::binary_iarchive ia( ifs ) ;
    ia >> b ;
    ifs.close() ;
    return 0 ;
}

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: boost::serialization について

#10

投稿記事 by h2so5 » 13年前

input stream error という例外が出ますね。
ストリームをバイナリモードにしたらうまく動くようです。

thaz

Re: boost::serialization について

#11

投稿記事 by thaz » 13年前

>> h2so5 様

うまくいきました!

コメントして下さった皆様、どうもありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る