2017-04-03 7 views
0

こんにちは私はProtobufをニューラルネットワークについての私の個人的なプロジェクトに利用しています。ここで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; 
} 

ネットワークは、次のように作成されます。

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()機能リンク機能は次のように定義されている

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); 

NGNET::ComputeLayerまたはNGNET::InputLayerを返します。 そして出力とNNETに好かれている:

nnetセグメントの障害にプログラムがクラッシュを削除さ
nnet->mutable_outputs()->AddAllocated(output1->getInternal()); 
nnet->mutable_outputs()->AddAllocated(output2->getInternal()); 

これは隠れたレイヤーが2回削除されたためだと思います。割り当てられたメモリを安全に解放する方法はありますか?

ありがとうございました。

+0

あなたのデザインに誰が何を所有しているか把握する必要があります。現在、複数のパーティーにすべて同じメッセージを所有していることを伝えるので、もちろんそれらはすべて削除しようとするため、2重破壊につながります。例えば。 'set_allocated_Foo'は' release_Foo'を介してその前の所有者から得たポインタに対して呼び出されるはずですが、それでも他のprotoが所有するポインタを渡します。 –

+0

@IgorTandetnikあなたが「あなたのデザインに誰が何を所有しているかを把握しなければならない」と言うとき、私のデザインはProtobufで使用するのに適していないか、または私が知らないProtobufの他の機能の? –

+0

私はあなたのデザインを本当に理解していません。表面上、あなたは共有所有権をモデル化しようとしているようです。 Protobufsは、各メッセージがフィールドの値を厳密に所有するように設計されています(メッセージ自体もメッセージである可能性があります)。あなたは 'LayerLink'プロトを単に' ComputeLayer'原型を指すだけで、前者自体が破壊されたときに後者を破壊しようとはしません。共有所有権は、protobufライブラリの外で、独自のクラスによってモデル化する必要があります。 –

答えて

0

add_allocated_*()およびset_allocated_*()の方法は、与えられたポインタの所有権を取得します。つまり、Protobufの実装は、メッセージが破棄されたときにそれらのポインタを削除するので、他のコードでこれらのポインタを後で削除しないようにする必要があります。

あなたがいるProtobufは、これらのオブジェクトの所有権を取得したくない場合は、代わりにコピーを作成する必要があります:あなたは強烈なメモリ割り当ての最適化を行っている場合を除き

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

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

は一般的に、あなたはおそらく呼び出したいことはありません」割り当てられた "protobufアクセサです。

関連する問題