using namespace std;
vector<int *> p;
vector<int *>::iterator i;
// (이하 생략)
i = p.begin();
while(i != p.end()) {
delete[] (*i);
p.erase(i);
i++;
} p.clear();
위 코드는 메모리 누수를 남기게 된다. 이유는 다음과 같다.
p.push_back(0);
p.push_back(1);
i = p.begin();
cout << "Data : " << *i << endl;
i++;
cout << "Data : " << *i << endl;
i = p.begin();
p.erase(i);
cout << "Data : " << *i << endl;
result :
0
1
1
그러니까 erase 명령에서 원소를 지운 뒤 자동으로 한 칸 넘어간다. 그러니까 위의 코드에서는
i++ 을 하면 안된다는 것이다. 두 칸 넘어가는 꼴이 되니까. erase 명령에 의해 i가 실제로 1칸
넘어가는지에 대해서는 컴파일러 명세를 더 읽어봐야 하겠지만 erase된 iterator는 이전의 것이
아니라는 것만은 분명한 사실인데 i++ 이란 코드는 이전의 iterator 를 기준으로 하는 것이므로
어디선가 오류가 발생할 여지가 충분히 있는 것이다.
위 코드의 문제에 대한 해결 방법으로
while(i != p.end()) {
delete[] (*i);
i++;
} p.clear();
혹은
while(i != p.end()) {
delete[] (*i);
p.erase(i);
} p.clear();
같은 코드들이 제시되었는데, 전자가 여러모로 안정적이지 않을까?
그 외 capacity에 대한 말이 나왔는데, 적어도 gcc에서는 기 할당된 capacity에 대해서 erase나
clear이 capacity를 초기화 시키지는 않는 것 같았다. 그 외에는...... 원소를 삽입할 경우에는
capacity가 변하니까 미리 reserve 해 두고 삽입하는게 빠를지도 모르겠다.
vector<int> p;
vector<int>::iterator i;
cout << "Capacity : " << p.capacity() << endl;
for(int j = 0; j < 12; j++) p.push_back(j);
cout << "Capacity : " << p.capacity() << endl;
p.clear();
cout << "Capacity : " << p.capacity() << endl;
result :
0
16
16
VC++ 은 capacity가 날아가는 건가? 정확히는 모르겠음(집에 VC++ 이 없어 ㅠㅜ)
'연구관련 > 프로그래밍' 카테고리의 다른 글
Visual studio .rc 파일 opened in another editor (MFC) (0) | 2011.04.11 |
---|---|
개인적으로 자주 쓰는 define 문 (0) | 2011.03.22 |
Visual Studio 2008, Vector erase할 때 주의사항 (0) | 2010.12.29 |
c++ vector 사용법 (0) | 2010.12.13 |
Messagebox : c 에서 AfxMessagebox 같은걸 쓰고 싶을때 (0) | 2010.12.08 |