6


0

std

vector(例えばT * dataが指す)に含まれるデータの所有権を別のコンストラクトに転送して、ベクトルがスコープ外になった後で "data"がダングリングポインターにならないようにする方法はありますか?

編集:私はデータをコピーする必要はありません(これは簡単ですが効果的な解決策ではないでしょう)。

具体的には、次のようにします。

テンプレートT * transfer_ownership(ベクトル

int main(){T * data = NULL; {vectorv; ... // vを動的に大きくするdata = transfer_ownership(v); } // //データを使って何か便利なことをする(後で解放する責任を持つユーザ)//たとえば、matlabのCインタフェースからのmxSetData(mxArray * A、double * data)}

これをエミュレートするために私の頭に浮かぶ唯一のものは以下のとおりです。

{vector * v = new vector(); // * vを大きくする... データ=(* v)[0]。 }

その後、データは後で解放されるか、(私の場合は)mxSetData(mxArrayA、doubledata)として使用されます。 しかしこれは小さなメモリリーク(vの容量、サイズなどを扱うためのデータ構造体)をもたらします。 しかし、データそのものではありません)。

漏れずに可能ですか。

5 Answer


5


簡単な回避策は、あなたが所有するものとベクトルを交換することです。

ベクトルmyown;

vector someoneelses = foo();

std :: swap(myown、someoneelses);

より困難ではあるがおそらくより良いアプローチは、ベクトルのためにあなた自身のアロケータを書き、それをあなたが維持するプールの外に割り当てさせることです。 個人的な経験はありませんが、それほど複雑ではありません。


5


std

vectorを使用することのポイントは、その中のデータについて心配する必要がないことです。

  • アプリケーション全体に沿ってベクトルを保存してください。

  • (不要なコピーを避けるために)const-refによって他の関数に渡してください。

  • そして、 `へのTへのポインタを期待して関数をフィードする

本当にベクトルを保持したくないのであれば、データをコピーする必要があります - 範囲外になったときに `std

vector`が内容を破壊することを保証するので、所有権を譲渡することはできません。 その場合は、 `std :: copy()`アルゴリズムを使ってください。


1


ベクトルに値が含まれている場合は、それらをコピーすることしかできません(std

copy、std :: swapなどを呼び出すと発生します)。 非プリミティブオブジェクトをベクトルに保存し、それらをコピーしたくない(そして別のデータ構造で使用したくない)場合は、ポインタを格納することを検討してください。


0


このようなものはあなたのために働きますか?

int main(){double * data = 0; {vector foo; // fooに要素をいくつか挿入する

data = new double [foo.size()]; std :: copy(foo.begin()、foo.end()、

// Matlab関数にデータを渡します。 []データを削除します。 0を返します。 }


-2


コンテナー間でデータをコピーするのではなく、コンテナー間でデータの所有権を転送したいので、以下のようにスマートポインターのコンテナーを使用することをお勧めします。

void f(){std :: vector> doubles; InitVector(2倍)。

std :: vector> newDoubles(double); }
標準コンテナは、カプセル化されたデータを常にコピーするため、コピーを作成せずに標準コンテナ間でデータの所有権を譲渡することはできません。 高価なオブジェクトをコピーするオーバーヘッドを最小限に抑えたい場合は、高価なデータ構造をラップするために参照カウントスマートポインタを使用することをお勧めします。 `boost

shared_ptr`はコピーするのがかなり安いのでこのタスクに適しています。