我使用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,我就崩溃了。
这是我用来设置Ipaddress
的代码//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]);
到此为止,没有崩溃...
如果我尝试使用GetReflection GetMessage获取指针,我会收到使用SetAllocatedMessage设置的相同指针地址,但是当我尝试使用它时会崩溃。第二个IpAddress UEIP崩溃但第一个没有....
答案 0 :(得分:0)
问题是您使用SetAllocatedMessage
将ipAddressMsg
的所有权分配给find_msg
,但ipAddressMsg
已归cdrMsg
所有。因为ipAddressMsg
现在由两个不同的protos拥有,所以你很快就会遇到问题,因为两个所有者最终都会尝试删除它。我认为您的代码在删除后会尝试使用该子消息。
请注意,通常使用protobuf时,包含单词release
或allocated
的方法有点高级功能 - 它们可以提高性能,但会增加复杂性并要求您执行更多操作内存管理。使用这些方法,很容易意外地遇到内存泄漏,双重删除和删除后使用。除非你真的需要表现,否则最好避免它们。在您的情况下,您只需分配到结果MutableMessage()
,而不是调用SetAllocatedMessage()
。