2016-10-04 2 views
0

私はprotobufを使用してクラッシュしました。私はそれを反射で使用する必要があります。Googleのprotobufでメッセージがクラッシュする

enum ipVersionType{ 
    ipv4 = 0; 
    ipv6 = 1; 
} 

message IpAddress { 
    required ipVersionType ipVersion = 1; 
    required uint32 IpPart1 = 2; 
    required uint32 IpPart2 = 3; 
    required uint32 IpPart3 = 4; 
    required uint32 IpPart4 = 5; 
} 
message TcpUdpCdr { 
    ... 
    optional IpAddress DestinationIp = 8; 
    optional IpAddress UEIP = 11; 
    optional uint32 PacketUpLink = 12; 
    .... 
} 
message cdr { 
    optional TcpUdpCdr tcpCdr = 1; 
} 

私はcdrなしでTcpUdpCdrを使用するとクラッシュしません。

私がcdrの中でTcpUdpCdrを使用するとクラッシュしました。ここ

は私がGetReflectionのGetMessageとのポインタを取得しようとした場合

、私が受け取る...私はTHERは何クラッシュではありませんここまでのIPアドレス

//Fill proto ip address sruct 
ProtoCdr::IpAddress * ipAddressMsg = new ProtoCdr::IpAddress(); 
ipAddressMsg->set_ipversion(ProtoCdr::ipVersionType::ipv4); 
ipAddressMsg->set_ippart1(pi_ipAddress.GetAddresPointer()[0]); 
ipAddressMsg->set_ippart2(pi_ipAddress.GetAddresPointer()[1]); 
ipAddressMsg->set_ippart3(pi_ipAddress.GetAddresPointer()[2]); 
ipAddressMsg->set_ippart4(pi_ipAddress.GetAddresPointer()[3]); 

google::protobuf::Message& find_msg = cdrMsg.GetReflection()->GetMessage... with local recursive function 
find_msg is of type TcpUdpCdr 
find_msg.GetReflection()->SetAllocatedMessage(
    &find_msg, 
    ipAddressMsg, 
    this->m_fdArray[m_iNestingSize-1]); 

を設定するために使用していたコードですSetAllocatedMessageで設定された同じポインタアドレスですが、使用しようとするとクラッシュします。なお、第2のIPアドレスUEIPのためではなく、最初の1のためにクラッシュ....

答えて

0

問題は、あなたがfind_msgipAddressMsgの所有権を割り当てることがSetAllocatedMessageを使用しているが、ipAddressMsgはすでにcdrMsgによって所有されていることです。 ipAddressMsgは現在2つの異なるprotoによって所有されているため、両方の所有者が最終的に削除しようとするため、すぐに問題にぶつかります。あなたのコードは既に削除された後にそのサブメッセージを使用しようとしていると思います。

注いるProtobufと一般的には、単語releaseまたはallocatedが含まれている方法は、高度な機能のビットであることを - 彼らは、パフォーマンスを向上させることができますが、彼らは複雑さを増し、より多くの手動メモリ管理を行うためにあなたを必要としています。これらの方法では、誤ってメモリリーク、二重削除、および削除後使用に陥ることは簡単です。パフォーマンスが本当に必要な場合を除き、それらを避けるのが最善です。あなたの場合は、SetAllocatedMessage()の代わりにMutableMessage()の結果に割り当てることができます。

+0

なぜ「ipAddressMsgは既にcdrMsgによって所有されている」と言われたのですか? TcpUdpCdrの下には2つのIpaddressMsgがあり、cdrMsgではなく、それぞれが個別のfieldDescriptorでSetAllocatedMessageで満たされます。私はSetAllocatedMessageがメモリを担当することを理解しています。パフォーマンスは私にとって重要です。そして私はprotobuf GetMessageで正しいメモリを返すメモリを調べます。 – davidbobo

+0

また、各SetAllocatedMessageは、ProtoCdr :: IpAddress *の個別の割り当てで呼び出されます。 – davidbobo

+0

申し訳ありませんが、あなたのコードを誤解していると思います。それはipAddressMsgが別のプロトによって所有されていない新しい割り当てであるように見えます。しかし、完全なコードを見ることなく、私はSetAllocatedMessage呼び出しが疑わしいでしょう - 私は 'allocated'メソッドと' release'メソッドのいずれも使用せずにコードを動作させ、その後最適化することを提案します。また、ValgrindまたはASANの下でコードを実行すると役立ちます。 –

関連する問題