2012-01-19 4 views
0

返された参照はいくらかのガベージ値を参照するので、私はリファレンスを返すことが悪いと思っていました。しかし、このコードは動作します(matrixはクラスである):リファレンスを返すことはできますか?

const int max_matrix_temp = 7; 
matrix&get_matrix_temp()  
{ 
    static int nbuf = 0; 
    static matrix buf[max_matrix_temp]; 

    if(nbuf == max_matrix_temp)  
     nbuf = 0; 

    return buf[nbuf++]; 
} 

matrix& operator+(const matrix&arg1, const matrix&arg2) 
{ 
    matrix& res = get_matrix_temp(); 
    //... 
    return res; 
} 

bufはここにやって、どのようにそれがゴミ値を有するから私たちを救うんは何?

+1

スペースには何がありますか? –

+0

'matrix&res max_matrix_temp();'それはコンパイルさえしますか? –

+0

[静的変数](http://en.wikipedia.org/wiki/Static_variable) –

答えて

0

私はどこでも宣言されていないので、関数の戻り値でスコープから外れることはないので、大丈夫です。 (それは実際にmatrixbufであるように見えますが、それはstaticなので、これも問題ありません)。

EDIT: R. Martinho Fernandesに感謝の意を表します。もちろんそれはmatrix bufなので、buf静的配列では、関数が返ってきて戻り値が有効なときに解放されないように一時的に割り当てられます。

+1

'' matrix buf [...] 'のように、' 'buf''という名前の' 'matrix'の配列。 –

+0

Argh。もちろん。 –

+0

一時的な割り当てはありません。静的記憶時間と一時記憶は異なる概念である。 –

2

bufは、それはそれは関数の呼び出しの間の値です保持を意味し、staticとして宣言されています

static matrix buf[max_matrix_temp]; 

それはint i = 0;としてスタック上に作成されていないのIE(非静的ローカル変数)になりますので、帰国しますそれへの参照は完全に安全です。

次のコードは、変数の値のメモリがスタック上にあるため、関数が返ってスタックを前の関数に戻してしまうため、関数のローカルのすべてのメモリ予約存在するのをやめる:

int * GetAnInt() 
{ 
    int i = 0; // create i on the stack 
    return &i; // return a pointer to that memory address 
} 

私たちが戻ってきたら、私たちは、スタック上のメモリの一部へのポインタを持っており、ダム運でそれはそれはまだ上書きされていないので、私たちが望む値を保持します - しかし、参照は無効です。なぜなら、スタック上のスペースが必要なときにメモリが使用できるようになったからです。

+1

IOW、* local *変数への参照を返しません。 – Xeo

+0

@xeo私はまだそれを得ることができません。適切に啓発してください。 –

+0

@ Xeo、IOW、あなたがやっていることを理解していない限り、参照を返さないでください(可能な残りの活動にも適用されます)。 –

0

これはポイントまでは安全ですが、非常に危険です。返された参照 はダングルすることはできませんが、クライアントコードが将来のある時点でそれを保持していれば、 クライアントは突然、その値が の新しい戻り値に変わるので、大きな驚きがあります。 を max_matrix_temp回以上呼び出すと、最終的に のデータを上書きすることになります。 std::string前日に

は、printfを使用してコードで、Iは "%s"指定子を使用したユーザー定義型の変換を戻すため、この 技術を使用し、引数が書式 関数への呼び出しでした。繰り返しますが、max_matrix_tempが弱点でした: printf私のタイプのより多くのインスタンスをフォーマットした場合、正しく出力されない データです。当時は悪い考えでしたが、今は悪い考えです。