boost 스마트 포인터 사용시 메모리 할당 해제 문제
글쓴이: dorado2 / 작성시간: 화, 2005/09/27 - 2:15오후
typedef struct _a { unsigned char a,b; } a; typedef struct _b { unsigned char c; unsigned char* d; } b; class pkt_buff { pkt_buff(unsigned char* data, int len); ~pkt_buff(); private: a m_a; b m_b; } pkt_buff::pkt_buff(unsigned char* data, int len) { memcpy(&m_a, data, 2); m_b.c = *(data+2); m_b.d = new unsigned char[len-3]; memcpy(m_b.d, data+3, len-3); ... } pkt_buff::~pkt_buff() { delete m_b.d; } typedef boost::shared_ptr<pkt_buff> pkb_ptr; typedef std::vector<pkb_ptr> pkb_list;
뭐 대충 위와 같은 식으로 짰는데요.
시리얼로 들어오는 패킷을 레이어별 헤더로 구분하고,
특정 데이터를 저장하는 부분이 필요해서요.
일종의 패킷 스니퍼를 작성하고 있습니다. 패킷 하나의 양은 1-200byte로 크지 않습니다. 그리고 들어오는 속도도 그리 빠르지는 않습니다 .
패킷 하나가 시리얼로 들어오면 (char array 형태로 통짜로 들어옵니다.) 위 pkt_buff 클래스를 이용해서 pkt_buff 객체를 하나 만들고, vector에 저장합니다.
들어오는 패킷을 vector에 쭈욱 저장하고, 화면에서는 자료구조에 담긴 패킷들을 하나하나 뽑아내서 화면에 패킷을 표시하는 프로그램입니다.
vector에 저장할 때, 자료형을 그대로 담는 건 메모리 오버해드가 크다고 해서 저렇게 포인터만 저장하는 걸로 알고 있습니다.
그런데 boost의 스마트 포인터는 scope를 벗어나면 자기가 메모리 해제를 하는 것으로 알고 있는데, 파괴자 ~pkt_buff() 부분도 수행을 하는 것입니까? 아니면 자기가 알아서 해주는 것인가요?
위에서 m_b.d 부분은 new로 할당을 해줘야 하는 부분이라서...
그리고, 위같은 구조로 사용해도 무방할까요?
더 효율적인 구조는 없을지 문의드립니다.
Forums:
스마트 포인터는 기본적으로 메모리를 해제합니다.
스마트 포인터의 용도는 무지 많지만...
예를 들어 예외가 발생할 부분을 스마트 포인터를 써서 간단하게 대체할 수 있다든지...
어쨋든 스마트 포인터는 힙에 할당된 메모리를 생성자로 넘겨줌으로써 포인터를 객체처럼 동작하게 합니다.
당연히 객체이기 때문에 scope를 벗어나면 메모리가 해제됩니다.
소멸자에 의해...
/***************************************************
* 가장 심플한 것이 가장 아름다운 것이다.
***************************************************/
Re: boost 스마트 포인터 사용시 메모리 할당 해제 문제
별 문제는 없어 보입니다만...
어차피 그 자료는 어딘가에 저장해야 하므로 vector에 담는다고 해서 오버헤드가
크게 달라지지는 않습니다. 다만 그 자료가 복사될 때는 얘기가 다르지요. 복사본
두 벌을 가지고 있느냐, 아니면 하나만 저장해놓고 포인터로 같은 자료를 참조하느냐의
차이입니다. pkt_buff 개체의 복사가 빈번하지 않다면 그냥 vector<pkt_buff>를
쓰는 것이 간단합니다.
그 말이 그 말 같은데... ^^; 물론 ~pkt_buff()도 수행됩니다. ~shared_ptr()이
내부에서 해주죠. 따라서 프로그래머가 직접 delete 할 필요는 없습니다.
~pkt_buff()에서 delete가 아니라 delete[]를 써야 합니다.
Re: boost 스마트 포인터 사용시 메모리 할당 해제 문제
생각해보니 unsigned char* 대신에 basic_string<unsigned char>를 쓰면
~pkt_buff()도 필요없겠습니다. 복사/대입도 저절로 해결되고요.
아 네..
답변 감사드립니다.
basic_string<unsigned char>에 대해서 찾아봐야 겠군요.
assign은 알겠는데, ~basic_string() 에서 다 delete되나 보군요.
boost 스마트 포인터를 쓰지 않고 vector<pkt_buff> 를 사용하는 경우에도 메모리 해제가 보장되나요?
그리고 사용하다 보면 선언만 하고 assign하지 않을 경우도 생길것 같은데, emtpy()나 capacity() 함수를 통해 그 여부를 알 수 있겠죠?
Re: 아 네..
string이 basic_string<char>을 typedef한 것은 알고 계시겠지요.
basic_string<unsigned char> 역시 똑같은 방법으로 쓰면 됩니다.
네. vector가 소멸될 때 각 원소들의 소멸자를 먼저 호출합니다.
empty()는 됩니다만 capacity()는 안 됩니다. 빈 스트링이라도 미리 메모리를
할당해놓는 구현도 가능한데 이때는 empty() == true 이지만 capacity() != 0 이지요.
댓글 달기