2012-01-25 2 views
2

내가 좋아하는 일을하고있다 : 나는 디버깅 할 때, x.abc 직접 할당 한 후 올바른 보이지만 담당자가 빠른 시간 이후 x.abc의 데이터가 쓰레기std :: vector :: operator []의 반환 주소는 무엇입니까?

struct ABC{ 
int p,q,r; 
}; 

struct X{ 
ABC *abc; 
X(ABC &abc) : abc(&abc) {} 
}; 

std::vector<ABC> vec; 
... //populate vec 

X x(vec[2]); 

. 그것은 내게 포인터가 지역 변수에 있다고 생각하게 만들고있다. 그러나 vector::operator[]은 참조를 반환하므로 그렇게 가능하다.

+1

코드가 더 필요합니다. vec은 무엇입니까? –

+0

조금 업데이트되어 명확 해졌습니다. –

답변

7

내부적으로 std::vector은 일반적으로 포함 된 요소의 동적 배열을 유지합니다. 벡터의 크기가 너무 커지고 이전 용량을 초과하면 새 배열을 할당하고 이전 요소를 복사 한 다음 이전 배열을 할당 해제합니다. 따라서 이전 배열에 대한 참조 또는 포인터가 유효하지 않게되고 사용하면 정의되지 않은 동작이 발생합니다.

포인터를 벡터에 저장하려면 벡터가 내부 버퍼를 재 할당하지 않도록해야합니다. 참조를하기 전에 벡터에 추가 할 모든 요소를 ​​추가 할 때까지 기다리거나 vector::reserve을 호출하여 용량이 충분히 큰지 확인할 수 있습니다.

그래도 인덱스와 함께 vector 개체 자체에 대한 참조를 저장 한 다음 매번 해당 인덱스에서 요소를 찾으십시오. 이렇게하면 벡터가 내부 버퍼의 크기를 조정하면 매번 벡터에 다시 인덱싱하므로 포인터가 가비지가되지 않습니다.

희망이 도움이됩니다.

+2

이것은'std :: vector <>'대신에'std :: deque <>'를위한 좋은 유스 케이스 일 것입니다. – ildjarn

+0

@ildjarn :'deque'에 대한 포인터는 무효화 될 수 있습니다. 아마도 여러분은'list'에 대해 생각하고 계셨습니까? –

+0

@Jesse : 이터레이터는 무효화되지만,'std :: deque <>'에 대한 _pointers/references_는'deque'에 앞 삽입이나 역 삽입시 무효화되지 않습니다. 왜냐하면 잠재적으로 기존의 재 할당을 할 필요가 없기 때문입니다 요소는'std :: vector <>'와 같아야한다 (C++ 11 §23.3.3.4/1 참고). – ildjarn