ページ 11

boost::serialization について

Posted: 2012年8月24日(金) 17:30
by thaz
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() ;
}

Re: boost::serialization について

Posted: 2012年8月24日(金) 17:49
by 結城
パッと見て推測でしかないのですが

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

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

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

Re: boost::serialization について

Posted: 2012年8月24日(金) 17:53
by h2so5
クラスA, B の定義を具体的に書いてほしいです。

Re: boost::serialization について

Posted: 2012年8月24日(金) 18:15
by thaz
クラス定義は以下の通りです。

<< 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 ;
} ;

Re: boost::serialization について

Posted: 2012年8月24日(金) 18:35
by 結城
<< thazさん
[tab=30]コードを書くときはコードタグで囲むようにしてくださいね
[tab=30]

コード:

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

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

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

コード:

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

Re: boost::serialization について

Posted: 2012年8月24日(金) 18:46
by thaz
>> 結城(元:Hinari) 様

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

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

Re: boost::serialization について

Posted: 2012年8月24日(金) 19:30
by h2so5
私の環境では正常に実行されました。

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();
}

Re: boost::serialization について

Posted: 2012年8月24日(金) 23:48
by thaz
すみません。
色々と試した結果、以下のコードが最小コードかと思うのですが、どうでしょうか?
最後の 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 ;
}

Re: boost::serialization について

Posted: 2012年8月24日(金) 23:56
by thaz
度々すみません。コードに誤りがあったので訂正します。
宜しくお願い致します。最後の 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 ;
}

Re: boost::serialization について

Posted: 2012年8月25日(土) 01:15
by h2so5
input stream error という例外が出ますね。
ストリームをバイナリモードにしたらうまく動くようです。

Re: boost::serialization について

Posted: 2012年8月25日(土) 11:47
by thaz
>> h2so5 様

うまくいきました!

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