2010-05-27 3 views
1

간단한 행맨 게임을 만들고 있습니다.C++ STL : 문자열 반복기에 문제가 발생했습니다.

void Hangman::printStatus() 
{ 
    cout << "Lives remaining: " << livesRemaining << endl; 
    cout << getFormattedAnswer() << endl; 
} 

string Hangman::getFormattedAnswer() 
{ 
    return getFormattedAnswerFrom(correctAnswer.begin(), correctAnswer.end()); 
} 

string Hangman::getFormattedAnswerFrom(string::const_iterator begin, string::const_iterator end) 
{ 
    return begin == end? "" : displayChar(*begin) + getFormattedAnswerFrom(++begin, end); 
} 

char Hangman::displayChar(const char c) 
{ 
    return c; 
} 

(결국, 내가 바꿀거야이 너무 displayChar() 표시 사용자가 짐작했지만, 간단하게 지금 난 그냥 모든 것을 돌려 있어요 경우 - 문자 또는.)

내가 구축하고 VS 2010에서 실행하면 팝업 상자가 나타납니다.

디버그 어설 션이 실패했습니다!

xstring 라인 : 78

표현 : 문자열 반복자하지 dereferenceable 내가 잘못 뭐하는 거지

?

+0

당신은 디버깅, 당신은 게시 된 코드가 원인이 동작을 확인하는 동안 역 추적을 받고 시도 할 수 있을까요? – jpalecek

+2

재귀 구현을 사용하는 특별한 이유가 있습니까? 반복 구현은 더 간단합니다. –

+0

@ 제임스 그래, 네 말이 맞아. 반복적으로 구현하고 이제는 작동합니다. –

답변

8
:
당신이 C + +0이있는 경우, 당신은 단지

std::for_each(correctAnswer.begin(), correctAnswer.end(), [this](const char& ref) { 
    std::cout << this->displayChar(ref); 
}); 

그 밖에 수행 할 수 있습니다, 당신은 다음과 같이 조금 보이는 뭔가를해야 할 것

문제가있는 평가 :

displayChar(*begin) + getFormattedAnswerFrom(++begin, end) 

이 통계를 실행하는 중 장담, 당신의 컴파일러는 첫째, begin을 증가 getFormattedAnswerFrom에 첫 번째 인수로 사용하기 위해 "다음"begin를 반환하고, 다음displayChar에 인수 begin를 역 참조 것이 분명하다.

beginend보다 1이면 begin != end이므로 displayChar(*begin) + getFormattedAnswerFrom(++begin, end)이 실행됩니다. 컴파일러가 begin을 증가하므로 지금은 begin == end이고, 역 참조는 begin이 유효하지 않습니다.

은 참조 : Order of evaluation in C++ function parameters

+0

C++ 스펙은 바이너리 연산자의 하위 표현식 평가 순서를 정의합니까? 아니면 사용자의 주장처럼 오른쪽에서 왼쪽으로가는 것이 일반적입니까? –

+0

+1 : 정의되지 않은 동작, 어떻게 내가 그것을 놓칠 수 있겠습니까? – jpalecek

+0

@David : 적어도 원시 타입에는 UB입니다. 사용자 유형은 불특정하지만 정의되지 않았을 수도 있습니다 (정확하게는 알지 못합니다). – jpalecek

0

correctAnswer이 비어있는 경우 correctAnswer.begin()correctAnswer.end()과 같으며 참조 할 수 없습니다.

+3

하지만 즉시 재귀를 종료해서는 안됩니까? – jpalecek

+3

그는 그 점에 대한 확인을하고 있습니다. begin == end 인 경우에도 displayChar (* begin) + getFormattedAnswerFrom (++ begin, end); 여전히 계산됩니까? – Anthony

+0

@jpalecek : 네, 맞습니다. – fbrereto

0

나에게 좋을 것 같습니다. 그러나 힙 또는 스택 손상으로 인해이 오류가 발생할 수 있습니다. 스택 추적을 잡고 correctAnswer 내부를 살펴보고 해당 Hangman 인스턴스가 올바른 개체인지 확인해야합니다.

또한 저는 여기에서 귀하의 기능에 대해 약간 걱정하고 있습니다. 그들은 매우 이상하게 보입니다. 그냥 std :: for_each로 바꾸지 않는 이유는 무엇입니까?

편집 @ 코멘트 :

struct helper { 
    Hangman* ptr; 
    void operator()(const char& ref) { 
     std::cout << ptr->displayChar(ref); 
    } 
}; 
helper Helper; 
Helper.ptr = this; 
std::for_each(correctAnswer.begin(), correctAnswer.end(), Helper); 
+0

for_each를 사용하여 솔루션을 보여줄 수 있습니까? –

+0

수정 됨. 문제가 발생하지 않아야합니다. – Puppy

+0

흥미를 자아냅니다. 상위 예제의 구문을 설명 할 수 있습니까? '[this]'의 의미는 무엇입니까? –