我需要删除传递给Google Protocol Buffer(protobuf)的对象吗?

5

我有简单的消息:

message SmallValue {
    int32 val = 1;
}
message Value {
    int32 val1 = 1;
    int32 val2 = 2;
    SmallValue val3 = 3;
}
message SendMessage {
    int32 id = 1;
    oneof message {
        Value value= 2;
}

我的代码片段:

// create new pointer for smallValue
SmallValue* smallValue = new SmallValue();
smallValue->set_val3(3);

// create new object value and set_allocated_val3
Value value;
value.set_val1(1);
value.set_val2(2);
value.set_allocated_val3(smallValue);

// create new object message and set_allocated_value
SendMessage message;
message.set_id(0);
message.set_allocated_value(&value);

// after some work, release value from message
message.release_value();

我的问题是:
1. 调用 message.release_value() 后,如果我没有创建 new 指针,那么不调用 delete &value; 是否可以?
2. 如果我没有调用 value.release_smallValue();,那么 smallValue 的内存会随着 value 自动释放吗?

// 我对 C++ 和 protobuf 都是新手。如果我的代码有什么奇怪的地方,请告诉我。

谢谢!


如果Google有一个使内存管理变得奇怪的库,我会感到惊讶。我希望你必须自己管理内存。话虽如此,你只能删除通过new分配的指针。value没有通过new分配;它在堆栈上分配。另一方面,你几乎永远不需要显式地输入newdelete;你应该使用std::unique_ptrstd::make_unique - Justin
@Justin 感谢你提到std::unique_ptrstd::make_unique。我会去了解一下。 - Thanh Nhan
1个回答

12

通常最好避免使用set_allocated_*release_*方法;这些方法提供了高级内存管理功能,除非您确实需要优化某些性能关键代码,否则不应该使用。

您可以像这样重写代码,以避免过多担心内存管理:

SendMessage message;
message.set_id(0);
Value* value = message.mutable_value();
value->set_val1(1);
value->set_val2(2);
value->mutable_val3()->set_val(3);

谢谢建议!我将更改为使用 mutable_* 而不是 newset_allocated_* ,但 release_* 部分不是我要更改的。这意味着在消息使用后将调用 release_*。这样做会导致内存泄漏,因为 protobuf 释放指针的所有权,而我没有删除它吗? - Thanh Nhan
是的,如果您调用了release函数,那么您必须自己删除指针以避免内存泄漏。也许调用'release_value()'的代码实际上应该调用'clear_value()'? - Adam Cozzette
太好了!实际上应该是 clear_* 而不是 release_*。非常感谢。 - Thanh Nhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接