2012-04-13 4 views
2

私はhereから、関数によって値によって返されたオブジェクトからconst参照を作成できることを知りました。しかし、今私は自分自身に尋ねました.1つはこのオブジェクトを置くので、安全であり、将来の関数呼び出しのスタックによって上書きされません。 mainは、スタックのオブジェクトから参照を作成するために起こっていることを知っていることでも実現可能ではありません、今return by valueからconst lvalue-referenceを作成しています:どのように動作しますか?

#include <iostream> 
using namespace std; 

struct A{}; 

A returnsmt(){ 
    int avariable; 
    cout<<"returnsmt stack: "<<&avariable<<endl; 
    return A(); 
} 

const A& proxyreturnsmt(){ 
    int avariable; 
    const A& middle=returnsmt(); 
    cout<<"proxyreturnsmt stack: "<<&avariable<<" A ptr: "<<&middle<<endl; 
    return middle; 
} 

int main(){ 
    int avariable; 
    const A& a=proxyreturnsmt(); 
    cout<<"main stack: "<<&avariable<<" A ptr: "<<&a<<endl; 
} 

、そのトリックは、それが非表示のポインタを渡すことはできません。

このコードを考えてみましょう独自のフリースタックバケット。これ++印刷物グラム上のコード:

returnsmt stack: 0x7fff3718bc0c 
proxyreturnsmt stack: 0x7fff3718bc28 A ptr: 0x7fff3718bc2f 
main stack: 0x7fff3718bc4c A ptr: 0x7fff3718bc2f 

スタックが下向きに成長する場合それは、オブジェクトがある場所は、効果的であること、のように見えるproxyreturnsmtのスタック。この参考資料を入手した後、function_with_big_stack_allocと呼んで、新しい使用のために古いproxyreturnsmtのスタックを取り戻すなら、どうして問題に陥ることはありませんか?

答えて

0

プログラムは未定義の動作を示します。 proxyreturnsmtでは、middleを一時オブジェクトにバインドします。その一時的なオブジェクトの有効期間は、middleが有効範囲外になるまで延長されます。

middleへの参照を返します。関数が復帰すると、そのオブジェクトが参照するオブジェクトは破棄されます。だからを呼び出す結果にaをバインドするmainでは、aは参照がなくなり、参照されるオブジェクトは存在しなくなります。

参照を使用しようとすると(存在しなくなった参照オブジェクトのアドレスを使用して)、プログラムは未定義の動作を示します。

+0

なぜg ++がそれについて文句を言っていないのだろうか?私はそれが返されないように簡単に「中間」を強制することができると思います。 –