2016-11-28 1 views
0

작업 코드를 얻는 방법뿐만 아니라 여기에 대한 자세한 설명을 찾고 있습니다. 나는 요소를 지우는 훨씬 더 짧은 코드를 작성하는 법을 안다. 나는이 테스트 코드를 삭제시 실패 지점을 찾아내는 데 여기에 썼다. 그것은 반복자가 무효화 될뿐만 아니라 .end() 반복자가되는 것처럼 보일 것입니다 ... 그리고 그것은 흥미 롭습니다.반복자 유효 기간

왜 작동합니까?

deque<shared_ptr<Vehicle>> data; 
    data.push_back(shared_ptr<Vehicle>(new Vehicle("porsche"))); 
    data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat"))); 
    data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat"))); 
    data.push_back(shared_ptr<Vehicle>(new Vehicle("bmw"))); 
    data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat")));  

    auto end = data.end(); 
    for(auto i = data.begin(); i != end;) 
    { 

     if((*i)->getName() == "fiat") 
     { 
      auto ti = i; 
      ++ti; 
      end = data.end(); //above erase, works but not logical 
      data.erase(i); 
      i=ti; 
     } 
     else 
     { 
      ++i; 
      end = data.end(); 
     } 
    } 

하지만 작동하지 않습니까?

deque<shared_ptr<Vehicle>> data; 
data.push_back(shared_ptr<Vehicle>(new Vehicle("porsche"))); 
data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat"))); 
data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat"))); 
data.push_back(shared_ptr<Vehicle>(new Vehicle("bmw"))); 
data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat")));  

auto end = data.end(); 
for(auto i = data.begin(); i != end;) 
{ 

    if((*i)->getName() == "fiat") 
    { 
     auto ti = i; 
     ++ti; 
     data.erase(i); 
     end = data.end(); //Bellow erase...more logical but crashes 
     i=ti; 
    } 
    else 
    { 
     ++i; 
     end = data.end(); 
    } 
} 

일부 구현 수준의 문제가있는 것으로 생각됩니다. 아마도 컴파일러 버그 일 것입니다. GCC 사용하기 4.8.2.

+0

코드에서 정의되지 않은 동작을 일으키는 버그가있을 가능성이 큽니다. 질문을 편집하고 [mcve]를 제공해야합니다. –

+0

반복자 동작은 컨테이너 유형에 따라 다릅니다. 정확히 '데이터'는 무엇입니까? – 1201ProgramAlarm

+0

코드가 추가되었습니다. 다른 장소에 오류가 없음을 보장합니다. 즉. Vehicle 클래스가 제대로 구현되었는지 등등. 코드를 집중시키고 깨끗하게 유지하기 위해 게시하지 않을 것입니다. – code

답변

0

정의되지 않은 동작이 호출됩니다. 대한 deque::erase 언어 스펙에서 :

양단 큐의 마지막 요소는 과거 - 더 - 끝 반복자 및 삭제 요소에 대한 모든 반복자와 참조를 무효화가 삭제 소거 작업. deque의 첫 번째 요소는 지우지 만 마지막 요소는 지우지 않는 지우기 작업은 지우개가있는 요소에 대한 반복기 및 참조 만 무효화합니다. 큐의 최초의 요소도 마지막 요소도 지우지 않는 지우기 조작 은 큐의 전의 요소의 전치사 반복자 및 모든 반복자와 참조를 무효화합니다.

귀하의 경우 end 이터레이터는 항상 방해 받고 있으며, 그것은 전혀 작동하지 않습니다. 두 번째 경우의 충돌은 data.end 호출이 아닌 i의 작업으로 인한 것일 수 있습니다.