2012-11-09 9 views
2

가능한 중복은 :
Problem with std::map::iterator after calling erase()나쁜 대한 액세스 메모리

당신은 내가 현재 데 문제로 가르치 려 수있을 수 있습니다. 문제는지도의 일부 요소를 지우려고 할 때 잘못된 액세스 메모리가 발생한다는 것입니다. 우리는 다음과 같은 형식 정의 가정 :

typedef std::map < std::string *, Document *, pStringCompare > Map; 

을 그리고 우리는 우리가 이미 모든 다음 코드의 실행 전에 (예를 들어) 두 가지 요소를 포함하는지도를 인스턴스화 한 가정합니다. 큰 작업이 코드 :

Map::iterator it = documents.begin(); 

std::string *s = it->first; 
Document *d = it->second; 

documents.erase(it); 

delete d; 
delete s; 

하지만 반복자와 루프에 노력하고있어 때, 나는 오류가 발생합니다.

for (Map::iterator it = documents.begin() ; it != documents.end() ; it++) 
{ 
    std::string s = * (it->first); 
    Document dd = * (it->second); 
    std::cout << s << " || " << dd; 
    documents.erase(it); // This line causes the bad access memory error. 
} 

도움 주셔서 감사합니다. 정말 고맙습니다!

Aleks

+1

있습니까? 나는 그것이'erase()'를 호출 한 후에 * invalid *가되기 때문에 증가 ('it ++')에서 일어날 것으로 기대한다. – Angew

답변

5

무효화 된 반복기에 액세스하고 있습니다. erase()에 전달하면 더 이상 유효하지 않으므로 for 루프에서 값을 증가시킬 수 없습니다. 자세한 내용은 Iterator Invalidation Rules을 참조하십시오.

루프는 무효화 반복자 접근 방지하기 위해 다음과 같이 구성해야합니다

for (Map::iterator it = documents.begin() ; it != documents.end() ;) 
{ 
    std::string s = * (it->first); 
    Document dd = * (it->second); 
    std::cout << s << " || " << dd; 
    documents.erase(it++); 
} 

난 정말 당신이 더 많은 문서를 읽고 여기에 무슨 일이 일어나고 있는지 이해하는 것이 좋습니다 있지만. 예를 들어 this을 참조하십시오.

행운을 빌어 요! 또한

+0

도움과 의사를 보내 주셔서 감사합니다. 매우 도움이되었습니다. – Aleks

0

: 당신은 오류가 발생하는 그 라인 확신

while ((Map::iterator iter = documents.begin()) != documents.end()) 
{ 
    std::string s = * (iter->first); 
    Document dd = * (iter->second); 
    std::cout << s << " || " << dd; 
    documents.erase(iter); 
}