Kumar Roshan Mehta
Kumar Roshan Mehta

Reputation: 3316

segmentation fault using protobuf

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

Answers (2)

Manideep Reddy
Manideep Reddy

Reputation: 91

You gave Gender as MALE for wife. That's why it gave segmentation fault

Upvotes: 3

druckermanly
druckermanly

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_ptrs.

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

Related Questions