2010-05-31 2 views
4

vector에 저장된 videoObjects의 Z- 인덱스 순서 재 지정을 수행하려고합니다. 계획은 vector의 첫 번째 위치에 놓일 videoObject을 식별하고, 지우고 첫 번째 위치에 삽입하는 것입니다. 아쉽게도 erase() 함수는 항상 잘못된 메모리 액세스를 발생시킵니다.Vector.erase (반복자)로 인해 잘못된 메모리 액세스가 발생합니다.

testApp.h :

vector<videoObject> videoObjects; 
vector<videoObject>::iterator itVid; 

testApp.cpp : 여기

내 코드입니다

// Get the videoObject which relates to the user event 
for(itVid = videoObjects.begin(); itVid != videoObjects.end(); ++itVid) { 
    if(videoObjects.at(itVid - videoObjects.begin()).isInside(ofPoint(tcur.getX(), tcur.getY()))) { 
    videoObjects.erase(itVid); 
    } 
} 

이 그렇게 간단해야하지만, 난 그냥 '어디에서 볼 수 없습니다 잘못 돌봐.

+0

왜 '(* itVid)'대신에 'videoObjects.at (itVid - videoObjects.begin())'입니까? –

+0

시도했지만, 다음 오류가 발생합니다 : 'std :: vector :: at (videoObject &)'에 대한 호출에 일치하는 함수가 없습니다. – xon1c

+0

'at()'을 사용할 필요가 없습니다. 조금도; 이터레이터의 역 참조는 지시 된 요소에 대한 참조를 반환합니다. –

답변

14

당신은 cplusplus.com에서

itVid = videoObjects.erase(itVid); 

견적을 수행해야합니다

[ vector::erase ] invalidates all iterator and references to elements after position or first.

Return value: A random access iterator pointing to the new location of the element that followed the last element erased by the function call, which is the vector end if the operation erased the last element in the sequence.

업데이트 : 당신이 당신의 상태 안에 현재의 요소에 액세스하는 방식이 오히려 이상한 보인다. 또한 요소를 건너 뛰고 범위를 벗어나는 오류가 발생할 수 있으므로 erase 이후에 반복기를 증가시키지 않아야합니다. 이것을 시도하십시오 :

for(itVid = videoObjects.begin(); itVid != videoObjects.end();){ 
    if(itVid->isInside(ofPoint(tcur.getX(), tcur.getY()))){ 
    itVid = videoObjects.erase(itVid); 
    } else { 
    ++itVid; 
    } 
} 
+3

Visual C++ 2010을 사용하는 모든 사용자에게 :이 기능을 사용하려면 반복기 디버깅을 사용하지 않도록 설정해야합니다 (기본적으로이 시나리오에서는 반복기 디버깅이 제대로 작동하지 않습니다). https://connect.microsoft.com/VisualStudio/feedback/details/557029/ –

+0

시도했습니다 : 'for (itVid = videoObjects.begin(); itVid! = videoObjects.end(); ++ itVid) { \t \t if (videoObjects.at (itVid - videoObjects.begin()). isInside (ofPoint (tcur.getX(), tcur.getY()))) { \t \t \t itVid = videoObjects.erase (itVid); 휴식; \t \t} 그러나 여전히 나쁜 메모리 액세스가 발생합니다 ... – xon1c

+0

@ xon1c, 내 업데이트 참조. –

1

반복자가 유효하지 않기 때문에 목록을 반복하는 동안 삭제할 수 없습니다. Erase의 반환 반복자를 사용하여 현재 반복기에 설정해야합니다.

0

erase 함수는 다음 유효한 이터레이터를 반환합니다.

당신은 while 루프를 확인하고 해당 검사와

iterator = erase(...) 

같이해야 할 것이다.

3

벡터에서 하나씩 요소를 지우는 것은 2 차적인 복잡성을 갖기 때문에주의하십시오. 구조에 STL!

#include <algorithm> 
#include <functional> 

videoObjects.erase(
    std::remove_if(
     std::bind2nd(
      std::mem_fun_ref(&videoObject::isInside), 
      ofPoint(tcur.getX(), tcur.getY()) 
     ), 
    ), 
    videoObjects.end() 
);