0

直後に変化しているあなたは、あなたがここにプロジェクトを表示してクローンを作成することができ、この問題の原因コードを参照したい場合:https://github.com/NickChapman/RuM/tree/63047e457745558403ea807534e4f5b9930cfeb8アドレスは、コンストラクタ

を注目すべきビットは、コンストラクタ内で、私が持っているということです(RuMParser.cppライン20):コンストラクタは私が終了直後次いで

this->globalScope = Scope(); 
std::cout << &(this->globalScope) << std::endl; 

及び(RuM.cppライン63):

std::cout << &(this->parser.globalScope) << std::endl; 

これらの出力は次のとおりです。

0x7fff57ac5318 
0x7fff57ac6988 

なぜ同じではありませんか?残りの時間は、アドレスは第2の値に固定されたままになります。なぜコンストラクタから離れた後に変更されますか?

最初のプリントアウトの直後にポインタを設定しようとすると、この問題が発生しました。ポインタは、2番目のコンストラクタが終了した古いアドレスへのポインタで、なぜ私は困惑しています。

これは、コピーコンストラクタまたはその性質の何かと関係があります。

編集:あなただけのソースを構築し、あなたを実行することができますしようとしている場合、参照のために:

cmake . 
make 

その後、x=1;$を入力

./rum 

プログラムがセグメンテーションフォールトが発生します。

答えて

1
this->parser = RuMParser(tokenList); 
std::cout << &(this->parser.globalScope) << std::endl; 

まず、一時的なRuMParserが作成されます。これは、最初のプリントを取得したときです。その後、一時的なコピーはthis->parserにコピーされます。つまり、globalScopeがデフォルトで再構築されます。したがって、後の印刷で異なる住所。

コードには疑わしい/慣れないものがかなりありますが、私はこの質問にとって重要なものだけに固執します。可能であれば、常にメンバ初期化子リストを優先してください。次のようにコンストラクタを書き直すことができます。

RuMInterpreter::RuMInterpreter(): 
     tokenList(std::make_shared<std::vector<Token>>()) 
    ,parser(tokenList) 
{ 
.... 
} 

それはまた、私が推測する効果的なC++の本の項目の1つです。

+0

ポインタを使用しないと、コピーコンストラクタの呼び出しを防ぐ方法がありますか? –

+0

オブジェクトを作成した後に割り当てるのではなく、最初の場所にオブジェクトを構築します。 'boost :: optional'をシェルとして使用して、後でオブジェクトを構築することもできます。 –

+0

@NickChapmanおそらくあなたがやっているはずのもので答えを更新しました。 – Arunmu

関連する問題