释放Protobuf生成的类会导致段故障

时间:2017-04-03 06:02:33

标签: c++11 protocol-buffers

您好我正在使用Protobuf进行关于神经网络的个人项目。

这是我的Protobuf定义:

syntax = "proto3";

package NGNET;

message InputLayer {
    string name = 1;
    uint32 size = 2;
}

message ComputeLayer {
    string name = 1;
    uint32 size = 2;
    repeated LayerLink inputs = 3;
}

message LayerLink {
    InputLayer il_input = 1;
    ComputeLayer cl_input = 2;
    uint32 output_size = 3;
    repeated float weights = 4;
}

message NNET {
    string name = 1;
    repeated ComputeLayer outputs = 3;
}

网络创建如下:

ComputeLayer output1 = ComputeLayer(10, "output1");
ComputeLayer output2 = ComputeLayer(10, "output2");
ComputeLayer hidden = ComputeLayer(100, "hidden");
InputLayer input1 = InputLayer(784, "input1");
InputLayer input2 = InputLayer(784, "input2");

output1.link(&hidden);
output2.link(&hidden);
hidden.link(&input1);
hidden.link(&input2);
hidden.link(&extra);

链接功能定义为:

void ComputeLayer::link(ComputeLayer* to_link) {
  NGNET::LayerLink* link = new NGNET::LayerLink();
  link->set_output_size(internal->size());
  link->set_allocated_cl_input(to_link->getInternal());
  internal->mutable_inputs()->AddAllocated(link);
}

void ComputeLayer::link(InputLayer* to_link) {
  NGNET::LayerLink* link = new NGNET::LayerLink();
  link->set_output_size(internal->size());
  link->set_allocated_il_input(to_link->getInternal());
  internal->mutable_inputs()->AddAllocated(link);
}

注意:getInternal()函数会返回NGNET::ComputeLayerNGNET::InputLayer

然后输出被NNET所喜欢:

nnet->mutable_outputs()->AddAllocated(output1->getInternal());
nnet->mutable_outputs()->AddAllocated(output2->getInternal());

删除nnet后,程序会因段故障而崩溃。

我相信这是由于隐藏图层被删除两次。有什么方法可以安全释放分配的内存吗?

感谢。

1 个答案:

答案 0 :(得分:0)

add_allocated_*()set_allocated_*()方法取得所有指针的所有权。这意味着您必须确保以后没有其他代码会删除这些指针,因为P​​rotobuf实现将在消息被销毁时删除它们。

如果您不希望Protobuf取得这些对象的所有权,您应该制作副本:

link->mutable_il_input()->CopyFrom(*to_link->getInternal());

nnet->mutable_outputs()->Add()->CopyFrom(*output2->getInternal());

通常,除非您正在进行激烈的内存分配优化,否则您可能永远不想调用"已分配的" protobuf访问器。