0

このコードに潜在的な危険はありますか?

void f(){
    std::vector<int> v;
    ...
    g(v);
}

void g(std::vector<int> &a){
    ... //store a by reference in variable blah (global)
}

f() の呼び出しが終了すると v は破棄されますが、何とか v を参照し続けます。何とか無効になりますか? ベクターの不要なコピーを作成せずにこれを行うより良い方法はありますか?

4

2 に答える 2

3

ジェームズが提供した答えに加えて、ぶら下がり参照なしで、ベクトル自体のヒープ割り当てなしで、不要なコピーなしで、最初のアイデアと同じ可読性を持つ 3 番目の可能性があります。

std::vector<int> global; //somewehere - you don't have it really global, do you?

void f() {
  std::vector<int> vf; 
  /* ... */
  g(std::move(vf));
}

void g(std::vector<int> vg) //by value!
{
  /* ... */
  global.swap(vg);
}

から移動vfするとf()vgの move-ctor が呼び出されます。つまり、以前に が所有していたリソースの所有権を取得するだけvfなので、不要なコピーや割り当ては行われません。swap()inは(したがって)への呼び出しの前に存在する場合にg()のみ機能します。ベクターを参照に保存したいと言ったので、実際にはストレージオブジェクトを作成し、呼び出しの前にはないと思います。次に、既存のオブジェクトと交換する代わりに、ストレージ オブジェクトを介して渡す必要があります。globalg()f()g()globalvgstd::move

合計すると、実際にはベクトルを 1 つだけ作成し ( vf)、他のすべてのベクトルは実際には同じでありmove、元のものに基づいているため、参照渡しと基本的に同じパフォーマンスが得られますが、ダングリング ref はありません。

(つまらない人向け: はい、ベクトルを移動することは ref を渡すことよりも少し多く、通常は 1 つをコピーする代わりに 3 つのポインターをコピーしてゼロにします。しかし、ヒープの割り当てやベクトルのコピーなどと比較すると、実際には何もありません。)

于 2012-12-06T09:01:50.253 に答える
0

はい、あなたが説明した問題があります。vヒープ上に作成する

void f()
{
    std::vector<int>* v = new std::vector<int>();
    // ...
    g(v);
}

void g(std::vector<int>* a)
{
    // Store in blah
    // But don't forget to delete it.
}

または、最初からグローバルとして持っています。

std::vector<int> v;

void f()
{
    g();
}

void g()
{
    // Use v;
}
于 2012-12-06T02:55:38.477 に答える