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++ 이 없어 ㅠㅜ)
Posted by 우주여행가
,