2011-01-05 26 views
0

私は次の例で問題が発生しています。最後の行は "abort has called"というエラーを生成しています。なぜこのようにすべきかわかりません。std :: vector abortの問題

この場合、わかりやすくするために、abc-> defの代わりに(* abc).defを使用しています。

#include <iostream> 
#include <string> 
#include <vector> 

class branch 
{ 
    public: 
     unsigned short n; 
     std::vector<branch> branches; 

     branch left() 
     { 
      return branches.at(0); 
     } 
}; 

void main() 
{ 
    branch trunk = branch(); 
     trunk.n = 0; 
     branch b1, b2; 
     b1.n = 0; 
     b2.n = 5; 
     b1.branches.push_back(b2); 
     trunk.branches.push_back(b1); 

    branch* focus1 = &(trunk.branches.at(0)); 
    branch* focus3 = &(trunk.left()); 

    std::cout<<trunk.left().branches.at(0).n<<std::endl; // ok 
    std::cout<<(*focus1).branches.at(0).n<<std::endl; // ok 
    std::cout<<(*focus1).left().n<<std::endl; // ok 
    std::cout<<(*focus3).branches.at(0).n<<std::endl; // problem 
} 
+0

どのようなOSですか?コンパイラは何ですか?また、 - >は(* p)よりもはるかに明確です.def –

+0

Windows VistaとVSC++ 2010 – alan2here

答えて

6

このコードの問題はtrunk.left()はブランチのコピーではなく、ブランチへの参照を返すことです。その結果、あなたのfocus3ポインターは、一時的なオブジェクトを指しています。その一時的なオブジェクトは、そのコード行が実行を終了した後すぐにクリーンアップされます。結果的に、最後の行でfocus3の参照を解除しようとすると、クラッシュの原因となるガベージ・データへのポインタに従います。

これを修正するには、leftにブランチへの参照を返すか、またはfocus3を参照参照にして、一時参照の存続期間を参照の有効期間まで延長します。

+0

ああ、 'const'リファレンスは良いですが、OPは' const'メソッドを使ってそれを使う必要があります。 – ephemient

+0

真実ですが、私はこれが良い考えであると確信しています。 (あなたが同意しない場合は、私と戦争を始めないでください:それは議論の価値がありません):-) – templatetypedef

+0

私は、ブランチを追加して、ブランチを追加して、left()の前に参照を使用しました。これは完全に機能しました。この場合、このソリューションもより効率的になり、編集や読み取りが可能になります。この例は、verryの異なる見た目のコードの単純化されたバージョンです。 – alan2here

関連する問題