2013-02-10 7 views
1

2 std :: lists가 있습니다. 목록 1에서 모든 항목을 삭제하고 두 번째 항목에 삽입하고 그 반대의 경우도 마찬가지입니다. 내 코드가 작동하지 않는 두번째 방법iterator erase "디버그 어설 션 실패"

for (std::list<Item *>::iterator it = list1.begin(); it != list1.end(); ++it) { 
     it = list1.erase(it); 
     list2.push_back(*it); 
    } 
it = list1.begin(); 
it = list2.erase(it); // because the last element is not deleted in the above loop 
list2.push_back(*it); 

대칭 코드 (액세스 위반 "리스트 반복자 dereferencable하지"를 받고). 두 목록 사이에 항목을 한 번 전송할 수 있지만 그 다음 오류가 발생합니다.

어떤 도움이 필요합니까?

+0

'std :: swap (list1, list2)'? – Johnsyweb

+1

@Johnsyweb'std :: list :: swap' 멤버 함수는 일정 시간 보장됩니다. 두 개의 포인터 (아마도 C++ 11의 크기 데이터 멤버)를 교환해야합니다. – juanchopanza

+0

@ juanchopanza : 분명히 좋을 것 같습니다. 'std :: swap' 함수는 여전히 제시된 구현보다 더 잘 수행 될 것입니다. – Johnsyweb

답변

3

이 용이하고 효율적 std::listswap 멤버 함수로 이루어진다 :

list1.swap(list2); 

이 일정 시간 복잡도를 갖는다.

+1

쉽게 가장 빠르고 최상의 답을 얻었습니다. – skypower

+0

@skypower 그런 다음 녹색 눈금 표시를 사용하여 수락해야합니다. – Csq

0

물론 list::swap을 사용해야합니다. 그러나 코드에 약간의 오해가 있음을 보여줍니다. list1가 돈 당신과 함께, end()이 inexistent (10)를 가리 킵니다 반복자 0,1,2,3,4,5,6,7,8,9 예를 들어, 요소의 원래 짝수가있는 경우

for (std::list<Item *>::iterator it = list1.begin(); it != list1.end(); ++it) { 
    it = list1.erase(it); // this effectively erase and destroy *it, 
       // and erase() return an iterator to the NEXT element. 
       // Now it=it+1 
    list2.push_back(*it); // you copy the NEXT element!! 
    // here is where we efectively get the ++it of the 'for'. 
    // When erase was used when ‘it’ was at end()-1, erase return end() 
    // The attempt to do it=end()+1 is an error probably detected by an assertion. 
} 

필요 없어 (지우기) 지우기. 이 'for'은 짝수 요소 (0,2,4,6,8)를 삭제하고 홀수 (1,3,5,7,9) 인 list2으로 복사합니다. 하지만 원래 list1에 홀수 요소가있는 경우, 예를 들어 0,1,2,3,4,5,6,7,8은 마지막으로 삭제 된 것이고, erase은 반복자를 존재하지 않는 9 = end(),에 반환하고 'for'는 어설 션을 통과시키지 않고 증분하려고 시도하십시오.