c++ - 谷歌 Protocol Buffer : "mutable_foo()" or "set_allocated_foo()"?

标签 c++ segmentation-fault protocol-buffers

我正在尝试使用 Google 的 protobuf。 我使用 subMessage,我用随机值设置它并将 subMessage 存储在 mainMessage 中。以下是适合我的情况的示例消息:

message subMessage{
    required int32 val1= 1;
    required int32 val2= 2;
    required int32 val3= 3;
    required int32 val4= 4;
}

message mainMessage{
    required subMessage sub = 1;
}

我的主要:

int main (int argc,char** argv){
    subMessage sM;
    mainMessage mM;
    sM.set_val1(10);
    sM.set_val2(9);
    sM.set_val3(8);
    sM.set_val4(7);

然后我尝试了:

mM.set_allocated_submessage(&sM);

但它会在程序结束时导致段错误(对象的破坏?)。解决它的唯一方法是手动调用 mM.release_submessage();

我也试过:

*mM.mutable_submessage()=subMessage;

我不明白为什么我会出现段错误,因为我的程序在之后立即停止(没有访问/写入我的 subMessage 或我的 mainMessage)。
根据Google's documentation :

void set_allocated_foo(Bar* bar): Sets the Bar object to the field and frees the previous field value if it exists. If the Bar pointer is not NULL, the message takes ownership of the allocated Bar object and has_foo() will return true. Otherwise, if the Bar is NULL, the behavior is the same as calling clear_foo()

似乎 mainMessage 在 set_allocated_foo() 之后拥有所有权,但它会导致段错误。另一方面,mutable_foo() 似乎复制了数据。我想避免重复数据,因为我将在 Raspberry 上运行低 RAM,但 set_allocated_foo() 目前对我来说太神秘了。我不明白这两者之间的区别...

你认为我应该使用 .set_allocated_foo() 并手动释放它,还是使用 .mutable_foo()

谢谢。

PS:我知道 this topic about set_allocated_foo()但我的问题不是删除与否,而是更多关于指针/数据的权利,并没有帮助我解决我的问题

最佳答案

您的代码通过 delete 删除本地变量运算符(operator)。这是未定义的行为。您的问题是您将指针传递给 LOCAL 变量,您应该分配 subMessage通过 new然后你可以将它传递给 mainMessage .

int main()
{
    subMessage sM;  // [1]
    mainMessage mM; 
    sM.set_val1(10);
    sM.set_val2(9);
    sM.set_val3(8);
    sM.set_val4(7);
    mM.set_allocated_submessage(&sM); // [2]

    // calls dtors in reverse order of definitions of instances
    dtor on mM is called // [3]
    dtor on sM is called // [4]
}

简而言之:

[1] sM被创建为局部变量

[2] 您将指针传递给局部变量 sM ,在这一刻mM取得 sM 的所有权

[3] 因为 mM拥有sM它试图删除 sM通过调用 delete ptrToSm 在 dtor 中

[4] 可能永远不会达到这个点,应用程序崩溃了

解决方法:

 subMessage* sM = new ...;
 mM.set_allocated_submessage(sM);

关于c++ - 谷歌 Protocol Buffer : "mutable_foo()" or "set_allocated_foo()"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53648009/

相关文章:

C——指向指针数组的指针

numpy - InfogainLoss 层

c++ - Cap'n Proto 在抛出 'kj::ExceptionImpl' 实例后终止调用

使用 selectannotation 时 iOS Mapkit 崩溃

c++ - 使用串口监视器arduino控制LED

c++ - 放置和默认构造函数

c++ - 安全销毁线程池

c - 尝试从用户输入的数组中获取最小数字时出现段错误

java - 如何使用 maven 从 Java target 11 的 protobuf 生成 java stub ?

c++ - 使用 clang 内置函数与标准函数的好处