7

std::vector に含まれるデータの所有権を別のコンストラクトに転送する方法はありますか (たとえば、T*data が指す)、ベクターが範囲外になった後に「データ」がダングリング ポインターになるのを防ぎますか?

編集:データをコピーしたくありません(これは簡単ですが効果のない解決策です)。

具体的には、次のようなものが欲しいです。

template<typename T>
    T* transfer_ownership(vector<T>&v){
    T*data=&v[0];
    v.clear();
    ...//<--I'd like to make v's capacity 0 without freeing data 
}

int main(){
    T*data=NULL;
    {
        vector<double>v;
        ...//grow v dynamically
        data=transfer_ownership<double>(v);
    }
    ...//do something useful with data (user responsible  for freeing it later)
   // for example mxSetData(mxArray*A,double*data) from matlab's C interface
}

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

{
    vector<double>*v=new vector<double>();
    //grow *v...
    data=(*v)[0];
}

その後、データは後で解放されるか、(私の場合) mxSetData(mxArray A,double data) として使用されます。ただし、これにより、小さなメモリリークが発生します(vの容量、サイズなどを処理するためのデータ構造体ですが、もちろんデータ自体ではありません)。

漏れなくできますか?

4

5 に答える 5

7

簡単な回避策は、ベクターを所有しているものと交換することです。

vector<double> myown;

vector<double> someoneelses = foo();

std::swap( myown, someoneelses );

より難しいがおそらくより良いアプローチは、ベクターの独自のアロケーターを作成し、維持するプールから割り当てさせることです。個人的な経験はありませんが、それほど複雑ではありません。

于 2009-11-13T14:47:12.607 に答える
6

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

  • アプリケーション全体でベクトルを維持します。
  • const-ref によって他の関数に渡します (不要なコピーを避けるため)。
  • また、Feed 関数は、T へのポインターを期待しています&v[0]

ベクターを本当に保持したくない場合は、データをコピーする必要がありますstd::vector。範囲外になるとコンテンツが破棄されることが保証されているため、所有権を譲渡することはできません。その場合は、std::copy()アルゴリズムを使用してください。

于 2009-11-13T14:52:47.300 に答える
1

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

于 2009-11-13T14:51:39.410 に答える
0

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

int main()
{
    double *data = 0;
    {
        vector<double> foo;
        // insert some elements to foo

        data = new double[foo.size()];
        std::copy(foo.begin(), foo.end(), &data[0]);
    }

    // Pass data to Matlab function.
    delete [] data;
    return 0;
}
于 2009-11-13T14:43:55.430 に答える
-2

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

void f()
{
    std::vector<boost::shared_ptr<double> > doubles;
    InitVector(doubles);

    std::vector<boost::shared_ptr<double> > newDoubles(doubles);
}

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

于 2009-11-13T20:32:46.403 に答える