您的位置:首页 > 其它

protobuf 使用中发现的一个问题

2013-05-16 18:08 429 查看
首先先说一下版本

protoc --version

2.5.0

然后说一下bug是什么,就是在把一个对象序列化成一个ostringstream后,如果再把另一个对象序列化到同一个ostringstream后,会发现第二个对象变成了两个对象。

即使ostringstream.clear() 后一样会有问题

先上协议文件, 标准的example

package lm;

message helloworld

{

required int32 id = 1; // ID

required string str = 2; // str

optional int32 opt = 3; //optional field

repeated int32 value = 4;

}

然后再上测试代码,

#include <iostream>

#include <sstream>

#include <stdio.h>

#include <string.h>

#include "helloworld.pb.h"

using namespace std;

using namespace lm;

using namespace google::protobuf;

int main()

{

helloworld hello;

hello.set_id( 100 );

hello.set_str( "this is a test ");

hello.set_opt( 200 );

for( int i=0; i<100; ++i)

{

hello.add_value( i );

}

ostringstream ss;

hello.SerializeToOstream( &ss );

string data = ss.str();

cout << data.length() << endl;;

cout << data << endl;

ss.flush(); //even flush is not work

ss.clear(); // attention:we have clear the stream

helloworld hello2;

hello2.set_id( 100 );

hello2.set_str( "this is a test ");

hello2.set_opt( 200 );

for( int i=0; i<100; ++i)

{

hello2.add_value( i );

}

hello2.SerializeToOstream( &ss );

string data2 = ss.str();

cout << data2 <<endl;

cout << data2.length() << endl;

return 0;

}

结果是

222

dthis is a test �     

                ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c

dthis is a test �     

                ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b dthis is a test �     

                ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c

444

显然,两个同样的hello对象连在一起了.

我一开始觉得这应该是protobuf的一个bug, 因为按照正常的stream使用标准,在我们clear,flush后,不应该在流中保留已有的东西。

为了验证我的想法,我马上又写了一个小test, 来排除是stringstream的问题。

代码如下,

#include <sstream>

#include <iostream>

#include <string>

using namespace std;

int main()

{

ostringstream ss;

ss.str("haha");

string data = ss.str();

cout << data.length() << endl;

ss.clear();

data = ss.str();

cout << data.length() << endl;

return 0;

}

我以为输出应该是4,0,但是很意外结果是4,4

这说明了,不是protobuf的问题,而是stringstream的问题,在clear,flush之后,并没有清空流。

最后上google搜了一下,为什么stringstream.clear 不起作用。

发现有大把人跟我遇到过一样的问题啊

在clear之前,加一句 ss.str( string() );

即设置一个空的string,通过这种方式来清空流。即,需要同时清空流,以及流中的string

做到这里先告一段落,后续我需要看看stringstream的原码,看看为什么不置空string就达不到清空流的目的!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: