2011-01-05 4 views
0

아래 예제와 달리, 마지막 줄에 "abort has called called"오류가 발생합니다. 나는 이것이 왜 있어야하는지 안다.std :: vector abort problem

이 경우 명확하게하기 위해 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을 임시 참조의 수명을 참조 수명까지 연장하는 const 참조로 설정하십시오.

+0

아,'const' 참조는 좋지만 OP는이를 사용하기 위해'const' 메소드를 만들어야합니다. – ephemient

+0

사실,하지만 저는 이것이 좋은 생각이라는 확고한 신념입니다. (동의하지 않는다면 논쟁의 여지가 없습니다.) :-) – templatetypedef

+0

브랜치를 & after를 추가하고 left()를 추가하여 referance를 사용했습니다. 이것은 완벽하게 작동했습니다. 이 경우이 솔루션은 훨씬 더 효율적이며 독서뿐만 아니라 편집도 가능합니다. 이 예제는 서로 다른 코드 조각을 단순화 한 버전이지만, – alan2here