2017-10-11 7 views
-3

저는 C++을 배우고 있습니다. 이제 반복기에 문제가 있습니다. 이것은 나의 경우입니다. 여기에이 코드가 있습니다.목록의 세그먼트 오류 <Object*> 반복자

// std::list<Dragon*> dragons = cave.getDragons(); 
for (std::list<Dragon*>::iterator it = cave.getDragons().begin(); it != cave.getDragons().end(); it++){ 
     os << std::endl << (*it)->getName(); 
} 

세그먼트 오류를 ​​반환합니다. 이것은 내 목록 내 getDragons() 방법 :

std::list<Dragon*> dragons; 
std::list<Dragon*> getDragons() const {return dragons;} 

그리고 제 질문은 ... 내가 이런 그렇게 세그먼트 오류가 이유는 무엇입니까,하지만 난 주석있는 변수 용을 사용하는 경우, 돈 ' 티? 감사!

+2

당신은'드래곤 * '의 목록을 가지고 있으며, 그 시작 부분에 반복자를 생성하고 목록을 버리고 파괴되도록합니다. 그런 다음 iterator와 비슷한 파괴 목록을 비교합니다. 어쨌든 범위 기반 for 루프를 사용하십시오 (foreach 루프 :'for (auto * dragon : cave.getDragons())) – Justin

+0

'getDragons()'는 복사본을 반환합니다. 어쩌면 레퍼런스가 필요할까요? –

+0

이 테스터이고, 그것은이 코드와 함께 작동하도록 있습니다. '자동 그것은 = cave-> getDragons을()() 시작;' 그것은 테스터 –

답변

1

getDragons() 그래서 당신은 getDragons()를 호출 할 때마다, 당신은 dragons 목록의 사본를 얻을, 값에 의한 std::list 반환합니다. 따라서 for 루프는 서로 다른 임시 std::list 개체의 반복자를 비교하며 유효하지 않은 반복자를 역 참조하려고합니다.

당신은 대신 더 이런 일을 수행해야합니다, 당신은 그렇지

for (Dragon *dragon : cave.getDragons()) { 
    os << std::endl << dragon->getName(); 
} 

: 나중에 C++ 11을 사용하는 경우,

std::list<Dragon*> dragons = cave.getDragons(); 
for (std::list<Dragon*>::iterator it = dragons.begin(); it != dragons.end(); it++){ 
    os << std::endl << (*it)->getName(); 
} 

또는 대신 for-range 루프를 사용 대신 getDragons()을 변경하여 std::list을 참조로 반환해야합니다.

그러면 원래의 for 코드가 작동하지만 모든 루프 반복마다 여전히 getDragons()이 호출됩니다. 이 로컬 변수 단일 호출의 결과를 캐시 최선이다

const std::list<Dragon*> &dragons = cave.getDragons(); 
for (std::list<Dragon*>::const_iterator it = dragons.begin(); it != dragons.end(); it++){ 
    os << std::endl << (*it)->getName(); 
} 

또는, 위와 같은 C++ 11 for-range 루프를 사용한다.

0

Remy가 설명했듯이 근본적인 오류는 목록의 복사본 사용 (오류가 발생하기 쉽지만 비효율적 일뿐만 아니라)입니다. 따라서 올바른 치료법은 이 아닙니다.은 그러한 사본을 만듭니다 (Remy의 대답은 여전히 ​​그렇게 제안합니다). 이를 위해 getDragons() 메서드는 참조를 반환해야합니다.

struct Cave 
{ 
    /* ... */ 
    std::list<const Dragon*> const&getDragons() const; 
}; 

또한, 당신은 auto 키워드를 사용해야 가능하면 (물론 사용 적어도 2011 표준).

for(auto const&dragon : cave.getDragons()) 
    os << std::endl << dragon.getName();