2017-02-28 8 views
2

클래스의 deque와 iterator를 멤버로 갖는 클래스가 있습니다. 다음 요소를 제공하는이 GetNext() 메서드가 있으며 이터레이터가 증가합니다. 바깥 쪽에서 클래스를 사용하여 비어있는 문자열을 검사하여 양 끝의 끝을 나타냅니다. 불행하게도 생성자가 호출되고 GetNext를 사용하여 마지막 요소를 가져 왔을 때 Heap 손상이 발생합니다. dequeator의 마지막 문자열 (빈 문자열) 이후에도 반복기가 여전히 증가하고 어딘가에을 메모리에 저장했기 때문에 이런 현상이 발생한다고 생각하십니까? 그러면 소멸자가이 메모리를 해제 한 다음 충돌이 발생합니다. 당신은 pNextItem은 역 참조 이전 list.cend() 동일한 경우 확인해야 Compilable and executable Exampleconst_iterator 멤버가있는 클래스의 소멸자를 호출 할 때 힙 손상이 발생했습니다.

+0

tutorialspoint.com – tzippy

답변

3

:

#include <iostream> 
#include <string> 
#include <deque> 


class Foo 
{ 
public: 
    Foo() 
    { 
     list.push_back("first elm"); 
     list.push_back("second elm"); 
     list.push_back(std::string());  
     pNextItem = list.begin(); 
    } 

    virtual ~Foo(){} 

    const std::string& GetNext() { return *pNextItem++; } 

protected: 

    std::deque<std::string> list; 
    std::deque<std::string>::const_iterator pNextItem; 
}; 


int main() 
{ 
    { 
    Foo foo; 
    std::cout << foo.GetNext() << std::endl; // "first elm" 
    std::cout << foo.GetNext() << std::endl; // "second elm" 
    std::cout << foo.GetNext() << std::endl; // "" 
    //third call sets the iterator past the last element and causes a segfault 
    std::cout << foo.GetNext() << std::endl; 

    } 

} 

다음은 예입니다. 이것은 정확히 foo.GetNext()의 세 번째 호출 이후에 발생하며 마지막 요소를 역 참조하고 반복기를 증가시킵니다.

referencedeque::end에서 :

이 컨테이너의 마지막 요소 다음 요소에 대한 반복자를 돌려줍니다.

이 요소는 자리 표시 자 역할을 수행합니다. 이를 시도하면 정의되지 않은 동작 인 이 발생합니다.

+0

에서 사용법 및 컴파일 가능한 코드에 대한 링크를 포함하도록 예제를 편집했습니다. 내가 클래스를 사용하는 코드를 추가했습니다. – tzippy

+0

@tzippy 그래서 좋은 추측을 만들었습니다 :) 대답을 업데이트했습니다. – AMA

+0

잘 추측;) 답변 주셔서 감사합니다. 이것이 좋은 방법일까요? : 'const를 표준 : : 문자열 및 GETNEXT() { \t 경우 (pNextItem == list.end()) \t \t 반환 *의 pNextItem; \t return * pNextItem ++; }' – tzippy