Reputation: 3316
I have started to learn protobuf, so please go gentle on me.
My protofile:
syntax = "proto3";
package apple;
message Message {
repeated int32 id = 1;
string name = 2;
wife mywife = 3;
enum phonetype
{
INVALID = 0;
MOBILE = 1;
HOME = 2;
}
phonetype type = 4;
}
message wife
{
string her_name = 1;
int32 age = 2;
enum sex
{
INVALID = 0;
FEMALE =1;
MALE=2;
}
sex orient = 3;
}
My C++ file:
using namespace google::protobuf;
using namespace std;
int main(int argc, char const *argv[]) {
apple::Message msg;
msg.add_id(77);
msg.set_name("xyz");
auto w_msg = make_shared<apple::wife>();
w_msg->set_her_name("abc");
w_msg->set_age(88);
w_msg->set_orient(apple::wife::MALE);
msg.set_allocated_mywife(w_msg.get());
cout << w_msg->her_name();
return 0;
}
The program compiles and build fine but when I run it gives me a segmentation fault, running with Valgrind gives me an invalid read error with too much information which I could not understand. I assume I am doing something wrong in msg.set_allocated_mywife(w_msg.get());
but I don't know exactly what? My purpose is to set Message message from already created wife message.
Upvotes: 3
Views: 7420
Reputation: 91
You gave Gender as MALE
for wife
. That's why it gave segmentation fault
Upvotes: 3
Reputation: 2741
When you call set_allocated_X
in protobuf, you transfer ownership.
You should not access that type via w_msg
after you call set_allocated_wife(...)
.
You should not use a shared pointer for the constructed wife
object, either, since that assumes that ownership is controlled by the (potentially many) shared_ptr
s.
Here is some code (based off of yours) that works properly and still lets you modify the wife
.
int main(int argc, char const *argv[]) {
apple::Message msg;
msg.add_id(77);
msg.set_name("xyz");
auto w_msg = make_unqiue<apple::wife>();
w_msg->set_her_name("abc");
w_msg->set_age(88);
w_msg->set_orient(apple::wife::MALE);
msg.set_allocated_mywife(w_msg.release());
cout << msg.mywife().her_name() << '\n';
auto* modifyable_wife = msg.mutable_mywife();
modifyable_wife->set_her_name("abc");
cout << msg.mywife().her_name() << '\n';
return 0;
}
Upvotes: 4