티스토리 뷰


이번 장은 간단하면서도 STL사용에 있어 중요한 장입니다.


제목과같이, 컨테이너의 요소로써 포인터를 사용한다면 컨테이너가 소멸되기전 필수로 각 객체의 메모리를 해제하라입니다.



void foo(){
vector<string*> v;
v.push_back(new string());
v.push_back(new string());
}
void main(){
foo();
}
view raw a.cpp hosted with ❤ by GitHub




위의 코드는 단번에 문제가 어디서 발생하는지 알 수 있습니다.


컴파일도 잘되며 실행하는데 런타임에 죽거나 하는 문제가 생기지 않을것입니다.


하지만 메모리의 누수는 심각한 문제로 다가옵니다.


작은 프로그램에서, 요즘같은 성능이 좋은 컴퓨터에서야 얼마나 문제가 발생하겠냐만


컨테이너에 들어가 있던 객체 몇십만개 였다면? 그 객체 자체의 크기가 크다면?


또는 그 객체가 물고 있던 메모리들은? (객체의 소멸자가 호출되어 물고 있던 자원을 해제한다면)


또는 서버와 같이 오랫동안 메모리에 올라가 있어야할 프로그램에서 꾸준히 메모리 누수가 발생한다면?



이러한 이유들로 메모리 누수에 대한 방비는 분명 세워져야 합니다.



이에 대한 방법들은 아래와 같은 방법을 사용하여 해결할 수 있겠습니다.


1. 컨테이너가 소멸되기전, 혹은 사용되고 해제되어야 할 시점에 수동으로 delete를 하여 관리한다.


2. for-each, functor를 이용하여 관리한다.


3. smart pointer를 이용하여 관리한다.





1번은 그야말로 추천하지 않는 원시적인 방법이라 할 수 있습니다.



void foo(){
vector<string*> v;
//...something do
for(auto it = v.begin() ; it != v.end() ; it++)
delete *it;
}
view raw item7-1.cpp hosted with ❤ by GitHub



다음과 같이 컨에이너가 소멸되기전 delete를 하기도전에


예외가 발생하여 foo함수를 종료해버린다면 string pointer들을 해제할 방도가 없어집니다.


이를 위한 대처로 try-catch-finally를 사용할 순 있겠으나 역시 손이 많이 가는 작업임은 분명합니다.






2번은 for-each문을 이용하여 관리하는 방법입니다.


사실 1번과 크게 달라 보이지는 않습니다.


for_each는 내부적으로 다음과 같이 구현되어 있습니다.


http://www.cplusplus.com/reference/algorithm/for_each/?kw=for_each


따라서 모든 원소를 순회하면서 넘겨진 함수를 통해 메모리를 해제할 수 있습니다.



struct Deleter{
template<class T>
void operator()(const T* ptr)const{
delete ptr;
}
}
void foo(){
vector<string *> v;
//do something;
for_each(v.begin(), v.end(), Deleter<string>());
}
view raw item7-2.cpp hosted with ❤ by GitHub









결론은 3번을 이용하는것입니다.


바로 스마트 포인터입니다.


스마트포인터에 대한 사용방법은 추후의 포스트나 구글에서 찾아 보시기 바랍니다.


마치 자바계열(?)의 가비지컬렉터와 비슷한 역할을 하게 해줍니다.


gc는 참조카운터를 이용하는 반면에 스마트포인터는 변수가 선언된 지역을 벗어나면 자동으로 지정된 삭제자를 호출하여


메모리를 해제합니다.



사용은 다음과 같이 하면 되겠습니다.


void foo(){
vector<shared_ptr<string>> sh_v;
sh_v.push_back(shared_ptr<string>(new string("A"));
sh_v.push_back(shared_ptr<string>(new string("B"));
//do something
//...
//end.
}
view raw item7-3.cpp hosted with ❤ by GitHub




위의 코드처럼 shared_ptr를 이용함으로써 메모리 해제를 위해 별도로 할게 없어집니다.


sh_v가 선언된 함수를 벗어나는 순간 컨테이너에 있던 string pointer들이 shared_ptr에 의해 자동으로 소멸되기 때문입니다.


특별히 삭제자를 지정하고 싶다면 역시 cplusplus에서 별도로 검색해 보세요.



이렇듯 컨테이너 사용에 있어 타입을 포인터로 지정할 경우 shared_ptr를 이용한다면 그만입니다.


단, auto_ptr은 금물입니다. auto_ptr은 유일한 소유권만을 허용하는데


stl contianer는 값의 복사를 기본으로 하기 때문에 사용에 있어 원치 않은 동작을 일으킵니다.


자세한건 item8을 참고하세요.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함