2016-10-04 102 views
0

我有一個使用protobuf的崩潰,我需要使用反射。谷歌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設置了相同的指針地址,但是當我嘗試使用它時會崩潰。它崩潰第二Ip地址UEIP,但不是第一個....

回答

0

的問題是,你使用SetAllocatedMessage分配的ipAddressMsg所有權find_msg,但ipAddressMsg已經被cdrMsg擁有。由於ipAddressMsg現在擁有兩個不同的原型,因此您將很快遇到問題,因爲兩個所有者最終都會嘗試刪除它。我認爲你的代碼在它已經被刪除後試圖使用該子消息。

注意,在一般以protobuf的,包含單詞方法releaseallocated有點先進的功能 - 它們可以提高性能,但它們增加了複雜性,並要求你做更多的手動內存管理。使用這些方法很容易意外地遇到內存泄漏,雙重刪除和刪除後使用。除非你真的需要這種表現,否則最好避免這種表現。在你的情況下,你可以指定結果MutableMessage()而不是調用SetAllocatedMessage()

+0

我不明白你爲什麼說「ipAddressMsg已經被cdrMsg所有」。在TcpUdpCdr下有2個IpaddressMsg,而不是在cdrMsg下,每個都由具有不同fieldDescriptor的SetAllocatedMessage填充。我明白,SetAllocatedMessage會照顧內存,性能對我很重要。我用protobuf GetMessage看內存,它將返回正確的內存使用。 – davidbobo

+0

而且每個SetAllocatedMessage都用一個不同的ProtoCdr :: IpAddress *分配來調用。 – davidbobo

+0

對不起,我想我誤解了你的代碼。它看起來像ipAddressMsg是一個不屬於另一個原型的新分配。儘管如此,沒有看到完整的代碼,我會對SetAllocatedMessage調用持懷疑態度 - 我會建議讓代碼在不使用任何'alloc'和'release'方法的情況下工作,然後再進行優化。它也可能有助於在Valgrind或ASAN下運行代碼。 –