2011-12-06 2 views
2

잃어 버렸습니다 : ++ 전에 함수 호출 (Z_UB-> set())이 없으면 std :: string 벡터의 반복자가 완벽하게 작동합니다. 나는이 같은 함수 호출을 이동하는 경우C++ 반복자가 무작위로 무효화됩니다.

std::vector<std::string>::iterator it = g_SPP.scenarios->getVector().begin(); 
std::cout << "begin of vector: " << *it << std::endl; 
Z_UB->set("s1", "scn2", 350); 
it++; 
std::cout << "second of vector: " << *it << std::endl; 

, 그러나 다음과 같은 출력

begin of vector: scn1 

만듭니다 : 다음은 코드의

std::vector<std::string>::iterator it = g_SPP.scenarios->getVector().begin(); 
std::cout << "begin of vector: " << *it << std::endl; 
it++; 
std::cout << "second of vector: " << *it << std::endl; 
Z_UB->set("s1", "scn2", 350); 

을 결과는 기대 이하입니다되는 행동 :

begin of vector: scn1 
second of vector: scn2 

는 Z_UB-> 설정() 함수 내부가 아무것도 남아 없지만 호출 자체 : 나는이 프로그램을 충돌합니다에 액세스 반복자를 생성 한 후 나는 Z_UB-> 설정() 함수를 호출한다면

void Parameter::set(std::string _i, std::string _j, float value) { 
//int i = indexSets[0]->backIndex(_i); 
//int j = indexSets[1]->backIndex(_j); 

//data2D[0][0] = value; 
} 

. Iterators에 대해 놓친 중요한 것이 있습니까?

+2

특정 문제를 진단하는 데 충분한 정보가 없습니다. 반복자는 "무작위로"무효화되지 않으므로 문제는 코드에 있지만이 게시물에서 명확하지 않습니다. 코드에서 문제가 발생합니다. 'Z_UB'는 실제로'Parameter' 타입입니까? 다른 유형이있을 수 있으며, 기본 '벡터'를 수정하는 것이 있습니까? 'vector' iterators는'vector' 내부 저장소의 크기를 변경하는 동안 무효화됩니다. – Chad

+1

getVector()는 벡터 또는 복사본에 대한 참조를 반환합니까? –

+0

벡터 복사본을 반환합니다 (&를 사용하지 않았기 때문에) – buhmann

답변

1

.getVector()가 벡터 복사본을 반환했습니다. 반복자를 완전히 다른 객체의 반복자의 끝점과 비교하는 것은 의미가 없습니다. 레퍼런스를 반환하면 문제가 해결되었습니다.

@Xeo 또한 더 나은 설명을 지적 :이 같은 복사본에서 반복자를 만들 때 :

std::vector<std::string>::iterator it = g_SPP.scenarios->getVector().begin(); 

복사가 즉시 따라서 방금 만든 반복자를 무효화 파괴된다. 따라서 이터레이터는 첫 번째 요소를 반환하지 않아야하지만 컴파일러 구현에 깊이 숨겨져있을뿐입니다.

+1

iterator가 즉시 무효화되고 정의되지 않은 동작 영역을 입력 했으므로 반환 된 복사본이 반복자를 만드는 행의 끝에서 즉시 소멸됩니다. – Xeo

1

std::vector<T>::iterator은 요소를 추가 할 때 내부적으로 벡터의 크기를 조정해야하는 경우 요소를 반복하면서 요소를 추가하거나 제거하면 무효화됩니다.

+0

예제 코드에서 이것은 여기서 일어나는 일이 아닙니다 ... – Benoit

2

g_SPP이고 변수가이면 변수에 대한 반복자는 임의의 변경 작업으로 무효화됩니다.


업데이트 -이 1998 년 ISO/ANSI 규격에서입니다 :

은 An 할당이 필요한 경우 시퀀스의 요소를 참조 모든 참조, 반복자, 포인터를 무효화 다음과 같습니다. 현재 capacity()이 목표 벡터 크기보다 작 으면 할당이 필요합니다.

  • iterator insert(iterator position, const T& x)
    • void reserve(size_type n) ,
    • void insert(iterator position, size_type n, const T& x)
    • ,
    • void insert(iterator position, InputIterator first, InputIterator last)

    소거 초기 소거 요소의 위치 후의 요소를 참조하는 모든 참고 문헌, 반복기, 및 포인터를 무효화한다. iterator erase(iterator position)

  • iterator erase(iterator first, iterator second)
  • 벡터 크기 조절 insert 또는 erase 하나를 호출하는 것과

    • . 23.2.4에 따라.2/6 :

      if (sz > size()) 
          insert(end(), sz - size(), c); 
      else if (sz < size()) 
          erase(begin() + sz, end()); 
      else 
          ; 
      
    +0

    흥미 롭습니다.이 참조를 뒷받침하는 참조를 추가 할 수 있습니까? – Benoit

    +0

    돌연변이 란 요소 추가 및 제거만을 의미합니까? –

    2

    몇 가지 가능성 :

    • 어느 당신이 좋은 reproductible 예를 들어이없는 : 어쩌면 당신의 첫 번째 실행에 당신은 당신의 벡터에 하나 개의 요소 만했다 resize(sz, c=value_type())는 것과 같은 효과가 있습니다 (어떻게 채워지나요?)
    • 또는 Z_UB->set에 대해 it을 확인하지 않았기 때문에 정의되지 않은 동작이 발생했습니다. 다형성 클래스입니까? set은 가상의 것입니까? -> 연산자에 과부하가 걸립니까?
    • 귀하의 앱이 멀티 스레드되어 있고 다른 스레드가 귀하의 컨테이너를 변형시키고 있습니까?
    +0

    -> set 함수가 오버로드되었지만 일부 다른 디버깅 출력을 추가했습니다. 내가 예상했던 것 하나만 호출되었습니다. – buhmann

    관련 문제