2016-05-13 5 views
1

動的配列A **を必要とする従来の関数があります。たとえば、ポインタのポインタの自動メモリ管理

A** array = new A*[100]; 
foo(array, 100); 
... 

void foo(A** a, int len) { 
    for(int i=0;i<len; ++i) { 
    a[i] = A::create(...); 
    } 
} 

私はこの配列を管理するために "スマートな"ポインタを使用できるかどうか疑問に思っていました。

boost :: scoped_array配列を使用できます。 array.get()はA **を返します。したがって、従来の関数でも動作します。しかし、私は配列のデストラクタは、トップレベルポインタを解放するだけで、第2レベルは解放しないと思います。

ptr_vectorは自動的にすべてを削除します。しかし、A **を返す方法はありません。

他の解決策はありますか?

+1

あなたが話すこのようなレガシー機能の例は、この質問を簡単に答えることができます。 – Dmitry

+0

ダブルポインタで処理される動的な2次元配列を実装するには、いくつかの方法があります。異なるものは異なる取り扱いを必要とする。 –

+0

@AviBerger 2d配列を作成するために使用できるブーストまたはSTLコンテナはありますか? –

答えて

4

A::create(...)のような呼び出しを使用してAPIを作成してポインタを返す場合、APIにはA::destroy(ptr)などのオブジェクトを破棄する補完的な呼び出しがあります。その場合には、次のカスタムデリータは適切でなければならない:

std::unique_ptr<A*, void(*)(A**)> array_ptr(
    new A*[100], 
    [](A** ptr) { 
     for(std::size_t i = 0; i < 100; i++) 
      A::destroy(ptr[i]); 
     delete[] ptr; 
    } 
); 
foo(array_ptr.get(), 100); 

EDIT最初のバージョンは遠く離れていたように見えたので、私は、私の答えを書き直しました。

+1

このようなベクトルを使うのはいい考えです。彼の投稿に追加されたOPのコードサンプルは、少なくとも行全体とおそらく行列全体がAPIの反対側に構築されていることを示唆しているため、このユースケースでは機能しない可能性があります。あなたが言及した行列クラスのいくつかのバージョンがおそらく必要になるでしょう。 –

+0

@AviBerger実際には、今見てみると、外側の配列には配列へのポインタが含まれていなくても、代わりに(APIで作成された)特異なオブジェクトがあります。 – user2079303

+0

このソリューションはいいですが、私たちは(array_ptr.get())[i]を実行する必要があります。 –

関連する問題