0

1を超える深さから返された右辺値参照を渡すときに問題が発生しました。

struct Data {
 std :: vector <int> data;
 Data () {
  data .push_back (1);
 };

 Data (Data && d)
 : data (std :: move (d .data))
 {}
};

Data && foo () {
 Data d;
 return std :: move (d);
}

Data && bar () {
 return std :: move (foo ()); // Crashes in autogenerated code
}

Data && baz () {
 return foo (); // Crashes in Data move constructor.
}

Data && bop () {
 Data d = foo ();
    return std :: move (d); // Crashes in autogenerated code.
}

int main () {
 Data d_foo = foo (); // This is fine.
 Data d_bar = bar (); // Crash.
 Data d_bar = baz (); // Crash.
 Data d_bop = bop (); // Crash.
}

std::vectorはダブルフリーになっていると思います。g ++(Ubuntu / Linaro 4.4.4-14ubuntu5)4.4.5を使用しています

上記のコードはあなたのために働きますか?私は何か間違ったことをしていますか、それともライブラリまたはコンパイラにバグがありますか?

(天国が)それがコンパイラである場合(gccには他の既知のC ++ 0xバグがあります)、ubuntuでgccをアップグレードまたはパッチするための適切な安全な方法があるかどうか誰かに教えてもらえますか?以前に試しましたが、サポートされていないパッケージが絡み合っています。

どうもありがとう。

4

3 に答える 3

6

関数から右辺値参照を返すことはほとんど意味がありません(std :: moveを除く)。これは、参照がおそらく一時的なオブジェクト、またはあなたの場合のようにスタック上のオブジェクトにバインドされており、それを返すとオブジェクトが失われるためです。

編集:

Data && foo () {
 Data d;
 return std :: move (d);
}

dスコープ外になると破棄されるため、ぶら下がっている参照を返します。

于 2011-01-07T20:27:31.553 に答える
5

右辺値参照を返すのではなく、値を返します。値は、参照によって右辺値として呼び出し元によって取得されます。あなたはただ持っているべきでありData foo()、ではありませんData&& foo()。それは未定義の振る舞いであるため、これらの作品のいずれかが純粋に偶然であるという事実。

于 2011-01-07T20:33:46.190 に答える
0

&&ローカルオブジェクトへの通常の参照/ポインタを返すこと以上に、ローカルオブジェクトにを返すことには何のメリットも期待できません。

値で返す必要があります。C ++ 03では、コンパイラーがコピーコンストラクターへの呼び出しを最適化できる状況です。C ++ 0xでは、これは(コピーを最適化できない場合、たとえば、コンパイラが異なるブランチから別のオブジェクトを返すときにそれを管理しない場合)、コピーコンストラクタ(使用可能な場合)の代わりに移動コンストラクタが呼び出されることを意味します。関数から値を取得します。

私が理解できる限り、移動セマンティクスは安全な場所で自動的に開始されるはずであり、右辺値参照パラメータータイプを使用すると、引数が右辺値(明示的に移動できるもの)であるかどうかを判断できます。

于 2011-01-08T10:29:57.213 に答える