vector 함정 기록

1647 단어
최근 데이터 구조의 메모리 점용 을 최적화 할 때 vector 함정 을 만 났 습 니 다.
알다 시 피 vector 내 pushback 대상 시, vector 가 현재 할당 한 메모리 공간 이 부족 하면 더 큰 (* 2) 메모 리 를 신청 하고 기 존 대상 을 복사 합 니 다. 마지막 으로 pushback 들 어 오 는 대상 은 끝 에 놓 습 니 다.
이 복사 과정 에서 이상 한 점 이 있 습 니 다. vector 는 기 존의 메모리 복사 본 을 새로 분 배 된 메모리 에 직접 사용 하 는 것 이 아니 라 새 메모리 에서 복사 구 조 를 호출 하여 현재 저장 수량 과 같은 요 소 를 구성 한 다음 에 오래된 메모리 의 요 소 를 분석 합 니 다.
vector 에 저 장 된 것 이 다음 과 같은 데이터 구조 라 고 가정 합 니 다.
class Object
{
public:
	//     ,    _buffer  
	Object()
	{
		_buffer = new char[1024];
	}
	~Object()
	{
		delete [] _buffer;
	}
private:
	char* _buffer;
};

vector 메모리 가 변 할 때 무슨 일이 일어 날 지 생각해 보 세 요.
만약 에 vector 에 Object 형식의 대상 이 존재 하고 vector 의 공간 은 size of (Object) 만큼 크다 고 가정 하면 이때 push 를 호출 하면back 새로운 대상 을 추가 하면 vector 가 메모 리 를 재배 치 하고 오래된 대상 을 새로운 메모리 로 복사 합 니 다.
그러면 상기 vector 에 따라 새 메모리 의 대상 은 복사 구 조 를 호출 하고 오래된 메모리 에 존재 하 는 이 대상 으로 새로운 대상 을 구성 합 니 다.복사 구조 함 수 를 명시 적 으로 정의 하지 않 았 기 때문에 기본 복사 구조 함 수 를 사용 하여 복사 할 것 입 니 다. 기본 복사 구조의 실현 방식 은 직접 할당 입 니 다.
그래서 새로운 대상 의buffer 멤버 는 오 랜 상대buffer 멤버 (포인터 가 직접 할당 되 었 습 니 다), 이 어 오래된 대상 은 방출 됩 니 다. 오래된 대상 은 방출 될 때 delete 합 니 다buffer 가 가리 키 는 내용, 이렇게 되면 새로운 대상 의buffer 멤버 들 은 철두철미 한 빈 지침 이 되 었 습 니 다!파멸 성 은 여기 서 끝나 지 않 았 습 니 다. 프로그램 이 아직 떨 어 지지 않 았 다 면, vector 의 메모리 가 다시 부족 할 때, 상기 절 차 는 이미 방출 된 메모 리 를 다시 삭제 하 게 될 것 입 니 다.
빈 바늘, delete 빈 바늘, 이보다 더 파괴 적 인 것 은 무엇 입 니까?
결론:
vector 에 위 와 같은 유형의 대상 을 저장 할 때 는 복사 구조 함 수 를 명시 적 으로 작성 하여 이러한 문제 가 발생 하지 않도록 해 야 합 니 다. 예 를 들 어 복사 구조 에 new 메모리 를 추가 하여 오래된 대상 의buffer 가 가리 키 는 내용 을 모두 복사 합 니 다 (직접 할당 포인터 가 아 닌)
참고 자료:
http://bbs.pfan.cn/post-292598-1.html

좋은 웹페이지 즐겨찾기