C++에서 vector 에 대한 두 개의 팁 공유
원래 이 글 의 제목 은'vector 에 관 한 두 개의 작은 구덩이'라 고 생각 했 는데 나중에 생각해 보 니 사실은 구덩이 가 아니 라 원리 적 인 것 을 이해 하 는 것 이 그렇게 투철 하지 않 았 다.업무 중 에 만난 많은 문 제 는 나중에 결국 기초 가 튼튼 하지 못 한 것 이다.
벡터 확장
이 문 제 는 매우 고전적 이지 만,조심 하지 않 아 밟 았 다.목표 요 소 를 복사 하 는 것 이 필요 합 니 다.목표 요소 의 집합 은 vector 에 저장 되 어 있 기 때문에 간단하게 생각 하면 다음 과 같은 코드(대체적인 의미)가 있 습 니 다.
void Duplidate(vector<Element>* element_list, Element* element) {
element_list.push_back(*element);
}
void Process() {
for (auto& package : package_list) {
if (IsNeedDuplicate()) {
Duplicate(element_list, package->element);
}
}
}
별 문제 가 없 는 것 같 습 니 다.현재 package 대상 이 복사 요 구 를 만족 시 키 는 지,필요 하 다 면 package 의 구성원 originelement 복사.UT 를 뛰 는 것 도 정상 이 고 테스트 할 때 coredump 입 니 다.코어 파일 을 보면 복사 할 때 걸 려 있 습 니 다.여기 서 나 는 처음부터 간단 한 복사 가 왜 coredump 가 있 는 지 이해 하지 못 했다.오랫동안 element 복사 장면 을 검 사 했 고 복사 구조 함 수 를 전문 적 으로 쓰 려 고 했 습 니 다.마침내 문득 크게 깨 달 았 다,originelement 포인터 가 가리 키 는 것 은 elementlist 안의 요소,elementlist 는 전체 프로 세 스 의 데이터 원본 이 고 packge 대상 은 패 키 징 의 중간 처리 대상 입 니 다.이전 개발 자 들 은 편 의 를 위해 패키지 대상 에 원본 element 지침 을 직접 저장 하 였 으 며,이 지침 은 vector 의 요 소 를 가리 키 고 있 습 니 다.그리고 제 가 새로 추가 한 논 리 는 원 초적 인 vector 에 요 소 를 추가 합 니 다.그러면 vector 의 확장 을 초래 할 수 있 습 니 다.vector 의 확장 은 전체적인 복 제 를 초래 하여 원래 이 요 소 를 가리 키 는 지침 이 모두 효력 을 잃 었 습 니 다.뒤의 package 대상 에 가서 origin 을 방문 합 니 다.element 에서 coredump 가 생 겼 습 니 다.
물론 디자인 적 으로 는 vector 요 소 를 가리 키 는 지침 을 저장 해 서 는 안 되 지만,여기 에는 오래된 코드 가 너무 많아 서 토론 하지 않 습 니 다.
vector::erase()
원인 은 내 가 코드 에 다음 과 같은 코드 를 추 가 했 기 때문이다(대체적으로).
void EraseElement(const vector<Element>::iterator& element_iter,
vector<Element>& element_list) {
while (element_iter != element_list.end()) {
element_list.erase(element_iter);
}
}
그리고 cr 의 친구 가 질문 을 했 습 니 다.element 입 니 다.iter 는 const 가 변 할 수 없 지만 함수 에 대응 하 는 요 소 를 지 웠 습 니 다.여기에 문제 가 있 지 않 습 니까?UT 는 이미 도 망 갔 지만 이런 표기 법 은 확실히 이상 하 다.그래서 기 회 를 빌려 vector:erase()의 실현 원리 와 용법 을 배 웠 다.erase(iterator)의 실현 원 리 는 사실 iterator 를 바 꾸 지 않 고 뒤의 요 소 를 하나씩 앞으로 이동 시 키 는 것 으로 iterator 가 가리 키 는 요소 자체 에 변화 가 생 긴 것 과 같 기 때문에 const 로 이 iterator 를 수식 할 수 있 습 니 다.그러나 여기 서 cosnt&를 사용 하 는 것 은 틀 리 지 않 지만 쓸모없는 수식 으로 오심 을 받 기 쉬 운 것 외 에는 실제 용도 가 없다.나 는 이전에 cpplint 를 수정 하기 위해 reference 를 const reference 로 바 꾸 었 다.
또한 erase 자체 가 위험 합 니 다.주로 erase 일 때 iterator 자체 에 변화 가 없 지만 가리 키 는 요소 가 변 했 습 니 다.많은 경우 iterator 는 자 연 스 럽 게 다음 요 소 를 가리 키 지만 이것 은 정의 되 지 않 은 행위 이기 때문에 이 안에 기대 할 수 없 는 부분 이 있 을 수 있 습 니 다.따라서 최종 적 으로 표 시 된 가 져 오기 재 할당(erase()은 다음 교체 기 를 되 돌려 줍 니 다.그러나 이 점 은 무시 되 는 경우 가 많 습 니 다).그러면 안전성 을 확보 할 수 있 습 니 다.더 안전 하고 추천 하 는 방법 은 remove 를 사용 하 는 것 같 습 니 다.if()여 기 는 전개 하지 않 겠 습 니 다.
void EraseElement(vector<Element>& element_list,
vector<Element>::iterator element_iter ) {
while (element_iter != element_list.end()) {
element_iter = element_list.erase(element_iter);
}
}
총결산이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
hdu 1717 소수 화 점수 2 (수학)소수 화 점수 2 레이 는 수학 시간 에 선생님 의 말씀 을 듣 고 모든 소수 가 점수 로 표시 되 는 형식 이 라 고 말 했다. 그 는 녹 기 시 작 했 고 곧 완성 되 었 다. 그러나 그 는 또 하나의 문 제 를...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.