2014-01-12 3 views
0

현재 그려진 이미지에서 재생 가능한 게임 수준을 만들 수있는 응용 프로그램에 대한 프로젝트를 진행 중입니다 (여기에서 찾을 수 있습니다 : Github). 이렇게하려면 이미지 처리에 openCV를 사용하고 있습니다.
내 문제는 감지 된 선 (레벨의 '벽')을 이미지로 그려야하는 기능입니다.때때로 반복기를 사용하는 세분화 오류

void LineFinder::drawDetectedLines(cv::Scalar color) 
{ 
    for (auto it = Play::getInstance()->getFinder()->getLines().begin(); it != Play::getInstance()->getFinder()->getLines().end(); ++it) 
    { 
     // The lines are stored in an std::vector<cv::Vec4i>, 
     // so basically in a vector which contains vectors with 4 elements each 
     cv::Point pt1((*it)[0], (*it)[1]); 
     cv::Point pt2((*it)[2], (*it)[3]); 

     // draws a line from pt1 to pt2 
     cv::line(Play::getInstance()->getFinder()->getImage(), pt1, pt2, color); 

     ++it; 
    } 
} 

이 기능을 실행하면 대부분 세그먼트 결함이 발생하지만 때로는 작동하고 결과는 예상대로입니다. 벡터에 요소가 들어 있다는 것을 알고 있습니다.
이렇게 생각할 수있는 원인은 무엇입니까?

EDIT : 흥미롭게도,이 기능을 사용하는 기능이 이미 성공적으로 한 번 실행되면 다시 반복해서 실행할 수 있으며 오류가 발생하지 않습니다.

EDIT2 : 나는 반복자와 세그먼트 오류를 ​​얻을 이유는 아직 모르지만, 그들없이 어떻게 든 작동합니다 : 당신은 두 번 반복자를 증가

void LineFinder::drawDetectedLines(cv::Scalar color) 
{ 
    for (int i = 0; i < Play::getInstance()->getFinder()->getLines().size(); ++i) 
    { 
     cv::Point pt1(Play::getInstance()->getFinder()->getLines()[i][0], Play::getInstance()->getFinder()->getLines()[i][1]); 
     cv::Point pt2(Play::getInstance()->getFinder()->getLines()[i][2], Play::getInstance()->getFinder()->getLines()[i][3]); 

     cv::line(Play::getInstance()->getFinder()->getImage(), pt1, pt2, color); 
    } 
} 
+0

당신이 세그멘트 폴트 라인/스택 추적을 찾기 위해 디버거를 사용 했습니까? 매번 동일하거나 매 실행마다 바뀌는가? – lostriebo

+0

오류의 원인이되는 행을 의미합니까? pt1이있는 줄입니다. – BlackMamba

답변

5

. 여기에 한 번 : 한 번 여기

for (auto it = Play::getInstance()->getFinder()->getLines().begin(); it != Play::getInstance()->getFinder()->getLines().end(); ++it) 

과 :

++it; 

그것은 당신이 정의되지 않은 동작의 결과로, end() 반복자 과거의 증가 일이 발생할 수 있습니다.

편집 : 다른 문제를 식별 할 수 있도록 게시물에 충분한 정보가 없다

, 특히 나는 모든 변수와 함수가 무엇인지 모른다. 나는 또한 전체 자식을 통해 크롤 링하고 싶지 않아요.

  1. Play::getInstance()->getFinder()->getLines() 항상 같은 컨테이너에 대한 참조를 반환 보장 : 그래서 여기

    몇 가지 가능한 문제인가?

  2. 반품되는 컨테이너는 반복되는 동안 수정되지 않는다는 보장이 있습니까?

  3. 컨테이너에 저장된 객체는 배열/벡터/...로 4 개 이상의 요소가 보장됩니까?

Edit2가 :

그럼 내가 저장소에서 짧은 모양을했다

, linefinder.cpp에서 오류가 :

std::vector<cv::Vec4i> LineFinder::getLines() 
{ 
    return lines; 
} 

getLines()하지 반환 동일한에 대한 참조를 않습니다 컨테이너를 호출 할 때마다 호출 할 때마다 복사본을 반환합니다. 따라서 하나의 컨테이너의 반복자를 for-loop의 다른 반복자의 반복자와 비교할 수 있습니다.당신이 반복자를 구성하기 전에

std::vector<cv::Vec4i>& LineFinder::getLines() 
{ 
    return lines; 
} 

또는 반환을 저장 : 어느 쪽 참조 반환에 정의를 변경

auto lines = Play::getInstance()->getFinder()->getLines(); 
for (auto it = lines.begin(); it != lines.end(); ++it) 
{ 
+0

그래,하지만 '++ it;'을 삭제 한 후에 아직도 이상한 행동이 있습니다. Btw.,이 줄은 같은 문제를 일으키는 while 루프가 있기 때문에 존재합니다. – BlackMamba

+0

@BlackMamba 나는 나의 대답을 확장했다 (다시) – Nabla